ここから本文です

VBSを使用して、ユーザごとに最も早い時刻を取得したいと思っています 現在、以...

aam********さん

2019/4/912:02:00

VBSを使用して、ユーザごとに最も早い時刻を取得したいと思っています

現在、以下のcsvファイルがあります



master_A.csv

date,user,u_no,action
2019/04/06 12:00,AAA,1,OFF
2019/04/06 11:00,AAA,1,GO
2019/04/06 10:00,AAA,1,ON
2019/04/06 13:30,BBB,2,END
2019/04/06 11:30,BBB,2,GO
2019/04/06 10:30,BBB,2,GO
2019/04/06 20:30,CCC,3,OFF
2019/04/06 18:30,CCC,3,GO
2019/04/06 8:30,CCC,3,ON
2019/04/09 19:15,AAA,1,END
2019/04/09 17:10,AAA,1,GO
2019/04/09 9:25,AAA,1 ON
2019/04/09 16:35,BBB,2,ON
2019/04/09 11:10,BBB,2,OFF
2019/04/09 18:50,CCC,3,GO
2019/04/09 7:55,CCC,3,OFF




このファイルから、日付毎に各ユーザの最も早い時刻の動作を出そうと考えています

目標とする結果.csv


date2,time,user,u_no,action
2019/04/06,10:00:00,AAA,1,ON
2019/04/06,10:30:00,BBB,2,GO
2019/04/06,8:30:00,CCC,3,ON
2019/04/09,9:25:00,AAA,1 ON
2019/04/09,11:10:00,BBB,2,OFF
2019/04/09,7:55:00,CCC,3,OFF


上記をADODBを使用して実現させようとしたのですが、
・group byでは[action]カラムの値が抜けなかった
・INNER JOINはcsv処理では使用できなかった

ために、以下の方法での実現を考えました


①master_Aでgroup byで抜けるものをひとまず抜く

"SELECT Format([date],'yyyy/mm/dd') as date2, Format(min([date]),'hh:nn:ss') AS time, user , u_no " & _
" INTO sep_master_A.csv " & _
" FROM master_A.csv " & _
" GROUP BY Format([date],'yyyy/mm/dd') , user , u_no;"


結果、以下を生成しました

sep_master_A.csv

date2,time,user,u_no
2019/04/06,10:00:00,AAA,1
2019/04/06,10:30:00,BBB,2
2019/04/06,8:30:00,CCC,3
2019/04/09,9:25:00,AAA,1
2019/04/09,11:10:00,BBB,2
2019/04/09,7:55:00,CCC,3



②日付と時刻を切ったファイルを作成

objADO.Execute "SELECT Format([日時],'yyyy/mm/dd') AS date2,Format(([日時]),'hh:nn:ss') AS time, action , u_no INTO sep_master_A.csv " & _
" FROM master_A.csv ;"


sep_master_B.csv

date2,time,action,u_no
2019/04/06,12:00:00,OFF,1
2019/04/06,11:00:00,GO,1
2019/04/06,10:00:00,ON,1
2019/04/06,13:30:00,END,2
2019/04/06,11:30:00,GO,2
2019/04/06,10:30:00,GO,2
2019/04/06,20:30:00,OFF,3
2019/04/06,18:30:00,GO,3
2019/04/06,8:30:00,ON,3
2019/04/09,19:15:00,END,1
2019/04/09,17:10:00,GO,1
2019/04/09,9:25:00,ON,1
2019/04/09,16:35:00,ON,2
2019/04/09,11:10:00,OFF,2
2019/04/09,18:50:00,GO,3
2019/04/09,7:55:00,OFF,3


③sep_master_A.csvとsep_master_B.csvを突き合せる

sep_master_A.csvのレコードを1行ずつ読み、
[date2][time][u_no]が一致したレコードに対して、最終カラムに[action]の値を入れる

例:sep_master_A.csv の1行目で[date : 2019/04/06][time : 10:00:00][u_no : 1]が一致している
sep_master_B.csvのレコード(2019/04/06,10:00:00,ON,1)の[action : on]を最終カラムに入れる
⇒ 目標とする結果.csv

を作成しようとしています


①・②はできたのですが、③がうまくいきません
(複数のカラムが一致した場合の作り方)

For i = 0 to c
If a(0) = d(0, i) Then
cr.WriteLine x & "," & d(2, i) & "," & d(0, i)
Exit For

の形式で書いてみたのですが、
書き方たがうまくいかず、
実行時に求めていたものが出ません
(実行結果が空白で出てしまう)


③の箇所をどのように作成すればよいのか、お分かりになられる方、ご教授願えませんでしょうか

閲覧数:
67
回答数:
2
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

lin********さん

2019/4/913:26:21

「master_A.csv」から直接「目標とする結果.csv」を出していますが、考え方が余りにも違うので、ダメでしたら、全く完全に無視してください。

このプログラムでは、「user」の項目が変わると、その1行上がも欲しいデータである、という考え方に基づいています。

すなわち、1行読み込んで、その1行を覚えておいて、もう1行読み込み、そのデータを処理して、前の方と「user」が変わったら、覚えておいた前の行のデータを書き出しています。

今は「Result.csv」というファイルに結果を書き出しています。

Option Explicit
Dim a, cr, cv, m, n, so, x, y, z
Set so = CreateObject("Scripting.FileSystemObject")
Set cv = so.OpenTextFile("D:\Programming\master_A.csv", 1)
Set cr = so.OpenTextFile("D:\Programming\Result.csv", 2, True)
x = cv.ReadLine
cr.WriteLine "date2,time,user,u_no,action"
y = cv.ReadLine
a = Split(y, ",")
n = a(1)
Do Until cv.AtEndOfStream
x = cv.ReadLine
a = Split(x, ",")
If a(1) <> n Then
m = Split(y, ",")
z = Split(m(0), " ")
y = z(0) & "," & z(1) & ":00," & m(1) & "," & m(2) & "," & m(3)
cr.WriteLine y
n = a(1)
End If
y = x
Loop
a = Split(y, ",")
z = Split(a(0), " ")
y = z(0) & "," & z(1) & ":00," & a(1) & "," & a(2) & "," & a(3)
cr.WriteLine y
cr.Close
cv.Close
Set cr = Nothing
Set cv = Nothing
Set so = Nothing
MsgBox("Finished!")

  • 質問者

    aam********さん

    2019/4/915:53:25

    ありがとうございます。
    実際は、
    ・一番早い時刻
    ・一番遅い時刻
    のそれぞれを出す想定です

    上記のスクリプトで、「一番遅い時刻」
    (各user項目の最上位のレコード)を出したい場合、
    どこを変えればよいのでしょうか?

    考え方としては、
    「user」の項目が変わった際の1番最初のデータを取る。ということになります

  • その他の返信(2件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2019/4/11 13:57:19

ありがとうございました。
本コードを参考に、必要な環境情報を適用したコードとして使用させていただきます

ベストアンサー以外の回答

1〜1件/1件中

glo********さん

2019/4/914:48:48

[date]と[u_no]でレコードを特定できるとするならば

Dim strPath
Dim strFile
Dim strCNstr
Dim strSQL
Dim rs
Dim strmsg

strPath = "C:\Users\username\Desktop\"
strFile = "master_A.csv"
strCNstr = "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & strPath & ";ReadOnly=1"

strSQL = "SELECT [Mst_A].* " & _
"FROM [@SOURCE@] AS [Mst_A] INNER JOIN " & _
" (SELECT CDate(Int([Wrk_A].[date])) AS DateG, Min(CDate([Wrk_A].[date]-Int([Wrk_A].[date]))) AS TimeM, [Wrk_A].[u_no], CDate([DateG]+[TimeM]) AS DateA " & _
" FROM [@SOURCE@] AS [Wrk_A] GROUP BY CDate(Int([Wrk_A].[date])), [Wrk_A].[u_no]) AS qrWork " & _
"ON ([Mst_A].[date] = [qrWork].DateA) AND ([Mst_A].[u_no] = [qrWork].[u_no]);"

strSQL = Replace(strSQL, "@SOURCE@", strFile)

Set rs = CreateObject("ADODB.Recordset")
rs.Open strSQL, strCNstr

Do Until rs.EOF
strmsg = strmsg & rs(0) & rs(1) & rs(2) & rs(3) & vbCrLf
rs.MoveNext
Loop
MsgBox strmsg

[date]と[u_no]でレコードを特定できるとするならば

Dim strPath
Dim...

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる