質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

Q&A

解決済

1回答

315閲覧

adodbで、カラムをそのまま出力させたい

amatsuno

総合スコア54

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

0グッド

0クリップ

投稿2019/03/29 09:52

ADODBを使用したSQL文で、カラムの値をそのまま出力させたいと思っています

ADODBを使用してcsvからレコードの抽出を行っているのですが、
関数処理を実施しないレコードについても、抽出を行いたいと思っています

コードを何通りか書いているのですが、
狙った結果が出力されません
(失敗したコード①・②)

どのように記載すればよいのでしょうか?
(Oracleで使用されているSQL(PLSQL)の形式では使用できないSQL分があるのでしょうか?)

CSVファイル:log_master1.csv
コンピューター名,日時,操作種別,期間,端末機No,端末機名
PC1,2019/2/6 9:56,終了,0:00:05,1,吉田1
PC1,2019/2/6 9:56,開始,0:00:05,1,吉田1
PC1,2019/2/6 9:41,継続,0:02:23,1,吉田1
PC1,2019/2/6 9:39,開始,0:02:23,1,吉田1
PC1,2019/2/6 9:23,終了,0:05:08,1,吉田1
PC1,2019/2/6 9:18,開始,0:05:08,1,吉田1
PC2,2019/2/6 15:18,継続,2:19:53,15,田中2
PC2,2019/2/6 12:58,開始,2:19:53,15,田中2
PC2,2019/2/6 12:06,終了,0:00:44,15,田中2
PC2,2019/2/6 12:05,開始,0:00:44,15,田中2
PC2,2019/2/6 12:01,終了,1:27:49,15,田中2
PC2,2019/2/6 10:33,継続,1:27:49,15,田中2
PC1,2019/2/8 8:56,終了,1:00:05,1,吉田1
PC1,2019/2/8 8:56,開始,10:00:05,1,吉田1
PC1,2019/2/8 8:41,継続,1:02:23,1,吉田1
PC1,2019/2/8 8:39,開始,1:02:23,1,吉田1
PC1,2019/2/8 8:23,継続,1:05:08,1,吉田1
PC1,2019/2/8 8:18,継続,1:05:08,1,吉田1
PC2,2019/2/8 14:58,開始,2:19:53,15,田中2
PC2,2019/2/8 14:06,終了,1:00:44,15,田中2
PC2,2019/2/8 14:05,開始,1:00:44,15,田中2
PC2,2019/2/8 14:01,終了,1:27:49,15,田中2
PC2,2019/2/8 11:33,開始,1:27:49,15,田中2

目標:このように出したい :logon_master1.csv
日付,起動時間,端末機名,操作種別
2019/2/6,9:18:00,吉田1,開始
2019/2/6,10:33:00,田中2,継続
2019/2/8,8:18:00,吉田1,継続
2019/2/8,11:33:00,田中2,開始

各日付毎の端末機名単位で、最も早い時刻のレコードのみを抽出し、
「日付」「起動時間」「端末機名」「操作種別」
を出力させたい
操作種別カラムは、最も早い時刻のレコードので記録されているものをそのまま出力したい

現在、正常に完了しているコード

sub on_time()

Dim objADO
Dim strPath

strPath = "C:\TESTCSV"

Set objADO = CreateObject("ADODB.Connection")
objADO.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & _
strPath & ";ReadOnly=0"

objADO.Execute _
"SELECT Format([日時],'yyyy/mm/dd') , Format(min([日時]),'hh:nn:ss') AS ontime, 端末機名 " & _
" INTO logon_master.csv " & _
" FROM log_master1.csv " & _
" GROUP BY Format([日時],'yyyy/mm/dd') , 端末機No , 端末機名 ;"

objADO.Close
Set objADO = Nothing

end sub

上記の状態では、「操作種別」カラム以外を、条件通りに抜出が成功している

失敗したコード①

sub on_time()

Dim objADO
Dim strPath

strPath = "C:\TESTCSV"

Set objADO = CreateObject("ADODB.Connection")
objADO.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & _
strPath & ";ReadOnly=0"

objADO.Execute _
"SELECT Format(max([日時]),'hh:nn:ss') AS ontime, 端末機名 , 操作種別 " & _
" INTO logon_master.csv " & _
" FROM log_master1.csv " & _
" INNER JOIN (SELECT 操作種別 , max(ontime) as MAXlogon from log_master1.csv " & _
" GROUP BY Format(max([日時]),'hh:nn:ss') ,端末機No , 端末機名) as master2 on 操作種別 = master2.操作種別 and ontime = master2.MAXlogon;"

objADO.Close
Set objADO = Nothing

end sub

 ⇒「結合式がサポートされていません」とエラーが出ます

失敗したコード②

sub on_time()

Dim objADO
Dim strPath

strPath = "P:\日本製粉csv\aaa\vbs"

Set objADO = CreateObject("ADODB.Connection")
objADO.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & _
strPath & ";ReadOnly=0"

'objADO.Execute _
'"SELECT Format(max([日時]),'hh:nn:ss') AS ontime, 端末機名 , 操作種別 " & _
'" INTO logon_master.csv " & _
'" FROM log_master1.csv " & _
'" INNER JOIN (SELECT 操作種別 , max(ontime) as MAXlogon from log_master1.csv " & _
'" GROUP BY Format(max([日時]),'hh:nn:ss') , 端末機No , 端末機名) as master2 on 操作種別 = master2.操作種別 and ontime = master2.MAXlogon;"

objADO.Execute _
"SELECT Format([日時],'yyyy/mm/dd') , Format(min([日時]),'hh:nn:ss') AS ontime, 端末機名 , 操作種別" & _
" INTO logon_master.csv " & _
" FROM log_master1.csv " & _
" GROUP BY Format([日時],'yyyy/mm/dd') , 端末機No , 端末機名 , 操作種別;"

objADO.Close
Set objADO = Nothing

end sub

 ⇒処理は成功するのですが、以下の結果となります

logon_master1.csv
日付,起動時間,端末機名,操作種別
2019/2/6,9:41:00,吉田1,継続
2019/2/6,9:23:00,吉田1,終了
2019/2/6,9:18:00,吉田1,開始
2019/2/612:05:00,田中2,開始
2019/2/612:01:00,田中2,終了
2019/2/610:33:00,田中2,継続

・・・2/8分についても続いて記載される

 ⇒操作種別ごとに出てしまいます

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

いろいろSQLとしておかしい部分があります。
vbsではデバッグが難しいので、
Accessなどの実行環境で動作を確認してから、
そのSQLをvbsに変換するといいでしょう。

各日付毎の端末機名単位で、最も早い時刻のレコードのみを抽出し、
「日付」「起動時間」「端末機名」「操作種別」
を出力させたい

まずは、サブクエリ内のSQLを実行環境(当方はAccess)で確認します。
下記のようになると思います。

sql

1SELECT 2 Format(T1.日時,"yyyy/mm/dd") AS 日付, 3 T1.端末機No; 4 Min(T1.日時) AS 最小日時 5FROM log_master1 AS T1 6GROUP BY Format(T1.日時],"yyyy/mm/dd"), T1.端末機No

提示のSQLだと GROUP BY に Max関数がありますが、それはできません。
あと、最も早い時刻なら、Min関数ですよね。

この集計クエリと元テーブルを結合すると

sql

1SELECT 2 Format(T2.日時,"yyyy/mm/dd") AS 日付, 3 Format(T2.日時,"hh/nn/ss") AS 起動時刻, 4 T2.端末機名, 5 T2.操作種別 6FROM 7 log_master1 AS T2 INNER JOIN 8 ( 9 ここに上記SQL 10 ) AS T3 11 ON T2.端末機No = T3.端末機No AND T2.日時 = T3.最小時刻;

提示のSQLだと ON句の結合式でテーブル名が省略していますが、それはできません。

上記SQLはAccessで動作確認できました。
これにINTO 句を挿入したものを、VBS上で SQL文として生成すればOKだと思います。

サブクエリだと複雑になるので、いったんサブクエリのデータをcsvに出力して、
それと元csvを結合するようにするとメンテナンスが楽かもしれまはせん。

投稿2019/04/10 07:55

hatena19

総合スコア33699

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amatsuno

2019/04/11 05:06

すいません。 実行先環境ではaccessがありません。 提示のSQLだと GROUP BY に Max関数がありますが、それはできません。 あと、最も早い時刻なら、Min関数ですよね。  ⇒すいません。最早と最遅の両方を出そうとしていたので、間違えました。  minです accessでは可能で、csvではできない処理(join関係など)で動作が難しいのが現状です。 これらは、csvへの操作も可能でしょうか?
hatena19

2019/04/11 10:24

adodb で接続してますので、基本はAccessと同じと考えていいでしょう。 当然、JOINも可能です。 accessがないなら MySQLとかでも基本的な部分は同じですので動作確認できると思います。 sqlfiddleなどWEBブラウザ上でSQLの動作確認できるサービスもありますのでそれを利用してもいいでしょう。
amatsuno

2019/04/11 23:59

ありがとうございます。 上記の内容で確認してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問