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

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

ただいまの
回答率

87.59%

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 738

score 50

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

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

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

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

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

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

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

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

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

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

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

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

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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/11 14:06

    すいません。
    実行先環境ではaccessがありません。

    提示のSQLだと GROUP BY に Max関数がありますが、それはできません。
    あと、最も早い時刻なら、Min関数ですよね。
     ⇒すいません。最早と最遅の両方を出そうとしていたので、間違えました。
     minです

    accessでは可能で、csvではできない処理(join関係など)で動作が難しいのが現状です。
    これらは、csvへの操作も可能でしょうか?

    キャンセル

  • 2019/04/11 19:24

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

    キャンセル

  • 2019/04/12 08:59

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

    キャンセル

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

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

関連した質問

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