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

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

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

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

Q&A

解決済

2回答

444閲覧

VBSを使用して、最も早い時刻を出力したい

amatsuno

総合スコア54

VBScript

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

0グッド

1クリップ

投稿2019/04/02 08:31

VBSを使用して、日付毎にcsvファイル内の各ユーザの最も早い日時を持つレコードを出力させたいと思っています

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: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: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: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 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分についても続いて記載される

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

group by を使用せずに、ユーザーごとに最も早い時刻([日時]カラムの最小値)を抽出する方法があるのでしょうか?

あるいは、コードにミスがあるのでしょうか?

お分かりになられる方、申し訳ございませんが
ご教授のほど、よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

自己解決

元ファイルがcsv(データの並びが決まっている)なので、
以下の考え方で対応しました

・最速の時刻が出た次のレコードは、必ず端末機Noが変わっている

対応方法:
端末機Noが変わったレコードがあった場合、その直前のレコードのみを抽出する

投稿2019/04/11 07:09

amatsuno

総合スコア54

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

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

0

CSVファイルは所詮テキストファイルでしかないので、それにOracleのようなデータベースの機能を期待するのは無理です。
CSVファイルにJOINの機能がないので、INNER JOINとかするのは無理なので、エラー表示が出たのでしょう。

投稿2019/04/02 09:02

coco_bauer

総合スコア6915

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

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

amatsuno

2019/04/02 09:14

ご回答ありがとうございます。 今回実施したいことは、  ・日付毎  ・端末機名毎 で、最も早い時刻(レコードの最下段)を抜き出したいだけなのですが、 DB的処理なし(ADODB処理なし)で可能でしょうか?
hatena19

2019/04/11 10:28

CSVファイル自体にはJOINの機能はないですが、ADODBはCSVファイルをデータベースのテーブルのように扱えますので、INNER JOIN は可能です。 エラーがでたのはSQLか間違っているからです。Oracleでも質問のSQLならエラーになります。
amatsuno

2019/04/12 00:02

ありがとうございます。 コードを見直して確認してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問