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

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

ただいまの
回答率

88.62%

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

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 413

amatsuno

score 40

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/02 18:14

    ご回答ありがとうございます。

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

    キャンセル

  • 2019/04/11 19:28

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

    キャンセル

  • 2019/04/12 09:02

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

    キャンセル

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

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る