「夫を成功」へ導く妻の秘訣 座談会

VBScriptでCSVファイルを最大5件のレコードになるように
ファイル分割しようとしています。
ただし、同じコードが複数のファイルに分かれないようにしたいです。

入力するCSVファイル(test_in.csv)は以下のような形式です。
(実際のファイルに項目行はありません)
連番,コード,フラグ,日付
01,0001,A,20091001
02,0002,A,20091001
03,0003,A,20091002
04,0001,U,20091003
05,0003,D,20091003
06,0004,A,20091003
07,0005,A,20091003
08,0001,D,20091005
09,0006,A,20091003
10,0006,A,20091003

※入力ファイルに同じコードのレコードが5件を超えることはありません)

上記の入力ファイルの場合は以下の3つのファイルに分割することになります。
【test_out_001.csv】
01,0001,A,20091001
04,0001,U,20091003
08,0001,D,20091005
02,0002,A,20091001

【test_out_002.csv】
03,0003,A,20091002
05,0003,D,20091003
06,0004,A,20091003
07,0005,A,20091003

【test_out_003.csv】
09,0006,A,20091003
10,0006,A,20091003

※コード"0003"のレコードは2件あるので、test_out_001.csvには出力せず、
 test_out_002.csvに出力します。
 コード"0006"についても同様でtest_out_003.csvに出力します。

処理の手順としては
入力ファイルのデータをコードでソートし、
1ファイルに5件を超えないように追加していくのかと思いますが、
ソートと5件制限はどのように記述すればよいでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (9件)

5件ずつ、しかもコードが生き別れにならない出力の例です。


Sub WriteData()
Dim JIS, UTF, F, T, N, E, C, P
F = 0
N = 0
Do Until f > CNT
  Set JIS = CreateObject("ADODB.Stream")
  JIS.Open
  JIS.Type = 2
  JIS.Charset = "shift_jis"
  N = N + 1
  P = "C:\ok\CSV\T" & Right("00" & CStr(N), 3) & ".csv"
  E = F + 4
  If E < CNT Then
    C = BLK(E).Code
    If C = BLK(E + 1).Code Then
      Do
        E = E - 1
        If C <> BLK(E).Code Then Exit Do
      Loop
    End If
  End If
  Do
    JIS.WriteText BLK(f).Seq & ","
    JIS.WriteText BLK(f).Code & ","
    JIS.WriteText BLK(f).Flag & ","
    JIS.WriteText BLK(f).Date & vbNewLine
    F = F + 1
    if F > CNT Then Exit Do
  Loop Until F > E
  JIS.SetEOS
  JIS.Position = 0
  Set UTF = CreateObject("ADODB.Stream")
  UTF.Open
  UTF.Type = 2
  UTF.Charset = "utf-16"
  JIS.CopyTo UTF
  JIS.Close
  Set JIS = Nothing
  UTF.SaveToFile P, 2
  UTF.Close
  Set UTF = Nothing
Loop
End Sub
    • good
    • 0
この回答へのお礼

分岐条件とループの脱出条件でここまで実現できるんですね…。
ご回答頂いたソースを実行してみて
実現したかった動作が確認できました。

後々、メンテナンスすることも考えられますので
一ステップごとに何の処理を行っているか理解しようと思います。

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

お礼日時:2009/11/16 15:55

並べ替えは以下のメソッドです。


Sub Sort(ByVal Fmi, ByVal Toi)
  Dim F, T, D, M
  F = Fmi
  T = Toi
  Set D = BLK(Fmi)
  Do
    Do While BLK(F).Comp(D) < 0
      F = F + 1
    Loop
    Do While D.Comp(BLK(T)) < 0
      T = T - 1
    Loop
    If F >= T Then Exit Do
    Set M = BLK(T)
    Set BLK(T) = BLK(F)
    Set BLK(F) = M
    F = F + 1
    T = T - 1
  Loop
  F = F - 1
  If F > Fmi Then Sort Fmi, F
  T = T + 1
  If T < Toi Then Sort T, Toi
End Sub
    • good
    • 0

ヘッダーなしだと1行目が項目名と解釈されてしまうのですが・・・



と聞かれそうな気がしたので、こちらもご参照のこと。

http://www.ken3.org/cgi-bin/test/test090-1.asp
    • good
    • 0
この回答へのお礼

ORDER句を使う方法でソースを作成し、
期待通りのソート結果を得ることが出来ました。

この方法ですと基本的なSQLされ知っていれば
かなり応用することができますね。

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

お礼日時:2009/11/16 15:14

>"DBQ=D:\\vbs\\test0001.csv;" & _



「\\test0001.csv」が余計です。TextDriverではフォルダを指定し、個々のcsvファイルが1つのテーブルのように扱われます。

>さらにこの方法で後々SQLを発行するはずですが、
>CSVには項目名がないのでORDER句が作れないような気がするのですが…。

select * from test0001.csv order by 2

でいけると思います。
だめだとしてもschema.iniを作ればいけます。

ちなみに、ずぼらな私はソート処理を自前で考えるのがイヤなのと、Text Driverだとソートだけでなく集計や抽出条件をつけることもできて応用がきくのでこちらをお勧めしていますが、nda23さんのご提示されている方法が真っ当でエレガントな気もしますので、ご検討ください。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
回答遅れて申し訳ないです。

せっかくですので両方の方法とも試してみたいと思います。

お礼日時:2009/11/15 17:28

SHIFT-JISに変換しますが、ファイルに保存する必要はありません。


読み込み処理は以下の通りです。

Sub ReadFile()
Dim JIS, UTF, ARY, TXT, TMP
Set JIS = CreateObject("ADODB.Stream") 'SHIFT-JIS側
JIS.Open
JIS.Type = 2 'テキスト形式という意味
JIS.Charset = "shift_jis"
Set UTF = CreateObject("ADODB.Stream") 'UTF-16側
UTF.Open
UTF.Type = 2
UTF.Charset = "utf-16"
UTF.LoadFromFile "C:\~\test_in.csv" '読み込み
UTF.Position = 0 '先頭に位置付ける
UTF.CopyTo JIS 'SHIFT-JISに変換(保存する必要は無い)
JIS.SetEOS
JIS.Position = 0 '先頭に位置付ける
UTF.Close 'UTF-16用オブジェクトにはもう用は無い
Set UTF = Nothing
Do Until JIS.EOS '読み込みループ
  TXT = "" '1行分のデータを初期化
  Do Until JIS.EOS '改行かEOSまでのループ
    TMP = JIS.ReadText(1) '1文字ずつ読み込む
    If TMP = vbLf Then Exit Do '改行なら抜ける
    TXT = TXT & TMP
  Loop
  ARY = Split(Replace(TXT, vbCr, ""), ",") '復帰を削除し、カンマで区切る
  Set TMP = New REC '新しいデータの入れ物をインスタンス化する
  TMP.Seq = ARY(0) '上記オブジェクトに記録(連番)
  TMP.Code = ARY(1) '上記オブジェクトに記録(コード)
  TMP.Flag = ARY(2) '上記オブジェクトに記録(フラグ)
  TMP.Date = ARY(3) '上記オブジェクトに記録(日付)
  CNT = CNT + 1 '配列要素数をインクリメント
  ReDim Preserve BLK(CNT) '配列を拡張する
  Set BLK(CNT) = TMP '配列の最後に追加する
LOOP
JIS.Close 'SHIFT-JIS用オブジェクトにはもう用は無い
Set JIS = Nothing
End Sub
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
この方法だとファイルに保存する必要もなく
二次元配列のようなことができるんですね。

こちらの方法も試してみたいと思います。

お礼日時:2009/11/15 17:34

>「■変換先のStreamを保存」


>まで試してみて変換先のファイルを開いてみたのですが、
>UTF-16BE形式になってしまいました。

ここ、

sto_in.SaveToFile "D:\vbs\test0001.csv",2

が、

sto_out.SaveToFile "D:\vbs\test0001.csv",2

です。せっかくSJISのストリームを作ったのに、元のUnicodeBEのストリームを保存しちゃだめです。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。その通りでした。
ADODB.Connectionを作成し、
以下の処理で変換先ファイルを開こうとしたのですが、
指定されたパスにファイルがないというエラーになってしまいました。
Dim objADOCon
Set objADOCon = CreateObject("ADODB.Connection")
objADOCon.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
"DBQ=D:\\vbs\\test0001.csv;" & _
"ReadOnly=0"

さらにこの方法で後々SQLを発行するはずですが、
CSVには項目名がないのでORDER句が作れないような気がするのですが…。

お礼日時:2009/11/12 18:43

この問題は3個の処理に分割すべきです。


(1)元データの読み込み
 UTF-16のデータを読み込んで、内部で処理できる形式に変換
(2)ソート
 各レコードをソート
(3)並べ替えデータの出力
 最大5件、かつ同一データが生き別れにならない出力

試しにプログラムしたら131ステップになってしまいましたので、
これをソックリ記載するのは難しいため、触りの部分を記載します。

'**** レコードの入れ物となるオブジェクト ****
Class REC
Dim Seq '連番
Dim Code 'コード
Dim Flag 'フラグ
Dim Date '日付
Function Comp(Other) '比較関数(自身と引数)
If Code > Other.Code Then
  Comp = 1 '自分の方が大きい
ElseIf Code< Other.Code Then
  Comp = -1 '自分の方が小さい
Else 'コードが同じ場合は連番で決める
  If Seq > Other.Seq Then '自分の方が大きい
    Comp = 1
  ElseIf Seq < Other.Seq Then
    Comp = -1 '自分の方が小さい
  Else
    Comp = 0 'コード、連番とも等しい
  End If
End If
End Function
End Class
'****** ここからメイン・メソッド ******
ReDim BLK(0) 'レコード(RECオブジェクト)の配列
Dim CNT 'レコード数(実際は配列の最大インデックス値)
CNT = -1 '配列の最大インデックス値なので、最初は-1

ReadData '(1)データの読み込み
If CNT > 0 Then Sort 0, CNT '(2)ソート
WriteData '(3)並べ替えたデータの書き込み
'****** ここまでメイン・メソッド ******

上記の例にはReadData、Sort、WriteDataのメソッドがありません。
メソッドの内容をご希望の場合は補足してください。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
>(1)元データの読み込み
> UTF-16のデータを読み込んで、内部で処理できる形式に変換
この「内部で処理できる形式」というのはNO.2の回答者様のように
いったんShift-JISに変換するのでしょうか…?

お礼日時:2009/11/12 17:42

元ファイルがUTF-16BEであるためにいろいろな便利機能が使えないので、いったんShift-JISへ変換したらよいと思います。


変換にはADODB.StreamのCopyToが使えます。
http://msdn.microsoft.com/ja-jp/library/cc364138 …

■元ファイルをStreamで読み込み。CharsetはUTF-16BE
■変換先のStreamを作成。CharsetはShift-JIS
■元ファイルのStreamから変換先のStreamへCoptyTo
■変換先のStreamを保存
■変換後のCSVファイルに対してText DriverでSQL発行
 :

あと、先に書いたコードでは以下の要件を見逃していました。その辺はうまくやってください。

>ただし、同じコードが複数のファイルに分かれないようにしたいです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
「■変換先のStreamを保存」
まで試してみて変換先のファイルを開いてみたのですが、
UTF-16BE形式になってしまいました。
↓このような書き方をしたのですが間違ってますでしょうか?
Dim sto_in
Set sto_in = WScript.CreateObject("ADODB.Stream")
sto_in.Charset = "UTF-16BE"
sto_in.Open
sto_in.Type = 2
sto_in.LoadFromFile("D:\vbs\test.csv")
sto_in.LineSeparator = -1
sto_in.Position = 0

'変換先Stream作成
Dim sto_out
Set sto_out = CreateObject("ADODB.Stream")
sto_out.Charset = "Shift-JIS"
sto_out.Open
sto_in.CopyTo(sto_out)
sto_in.SaveToFile "D:\vbs\test0001.csv",2
sto_in.Close
Set sto_in = Nothing
Set sto_out = Nothing

お礼日時:2009/11/12 17:23

文字コードの制約はなくなったと考えてよいでしょうか。


入出力ともSJISでよい前提として、私ならばこんな感じでしょうか。

■CSVの読み込みにはADOとODBC Text Driverを使用します。
 VBS CSV Text Driver等で検索してみればサンプルが見つかります。
 
■ソートはCSV読み込み時にSQLで指定するか、ADODB.Recordsetの
 Sortプロパティがたぶん使えます。

■5件づつの出力はただ単にループをまわしながら5件ごとに
 出力ファイルを切り替えていくだけかと思います。
 
Dim oRst '結果を格納したRecordset
Dim oOutFile '出力ファイル

lCnt = 0
Do While Not oRst.EOF
'5件ごとに出力ファイルを変える。
If lCnt Mod 5 = 0 Then
Set oOutFile = FSO.CreateTextFile("test_out_" & Right("000" & lCnt \ 5 + 1, 3) & ".csv")
End If

'ここの編集が格好悪いですが。。。
oOutFile.WriteLine oRst.Fields(1).Value & "," & ・・・・

lCnt = lCnt+1
oRst.MoveNext
Loop

この回答への補足

ご回答ありがとうございます。
丁寧に回答して頂いたのですが、
入力ファイルの文字コードは"UTF-16BE"です…。
肝心なことが質問内容から漏れてしまいました。
大変申し訳ありません。

補足日時:2009/11/11 00:40
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qwshでcsvファイルのソートを行いたい

wshのプログラムで困っているため教えてください。

wshでcsv(カンマ区切り)のファイルのソートを行い、Escel形式で保存するプログラムを書いています。
調べてみたところ、wshではソート関数がないようで、
adodbのsort関数を使用して対処しようとしていますが、どうもうまくいきません。
(※adodbの必要はないのですが、ExcelVBAのsortのコードを書こうとするとエラーになってしまったので、adodbにしています。)

<仕様>
csvファイルのソートのキーになるのは、「判定区分」の値で昇順に行いたいです。
csvファイルの一行目は、カラム名としてソート対象にはなりません。
読み込んだcsvファイルをexcel形式に保存したいです。

■csvファイルの形式は、以下のような形です。

性別,年代,判定区分,生年月日,日付
女性,10,0,2010/01/10,2013/7/7 23:57
男性,50,2,2000/03/30,2013/7/7 13:7
女性,10,0,1990/01/20,2013/7/7 15:22
女性,20,1,2001/12/10,2013/7/7 8:10
*-----------------------------------
<ソース>
Set con = CreateObject("ADODB.Connection")
With con
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path & ";" _
& "Extended Properties='text;HDR=Yes;FMT=Delimited'"
.Open
End With

Set rec = CreateObject("ADODB.Recordset")
rec.Open "select * from " & csvfile & " order by 判定区分", con
*-----------------------------------
うまくいかないため
↓でも書いています。
*-----------------------------------
Const adDate = 7
Const adVarChar = 200
Dim ans

Set objADO = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Set re = CreateObject("VBScript.RegExp")

rs.Fields.Append "性別", adVarChar, 255
rs.Fields.Append "年代", adVarChar, 255
rs.Fields.Append "判定区分", adVarChar, 255
rs.Fields.Append "生年月日", adDate
rs.Fields.Append "日付", adDate

rs.Open

ans = ""
rs.Sort ="判定区分 ASC"
rs.MoveFirst
Do While Not rs.EOF
ans = ans & rs.Fields(0).Value & vbCrLf
rs.MoveNext
Loop
MsgBox ans


エラーになってしまいます。
ソート処理だけですでににっちもさっちもいかないため、教えていただきたいです。

どうぞ宜しくお願いいたします。

wshのプログラムで困っているため教えてください。

wshでcsv(カンマ区切り)のファイルのソートを行い、Escel形式で保存するプログラムを書いています。
調べてみたところ、wshではソート関数がないようで、
adodbのsort関数を使用して対処しようとしていますが、どうもうまくいきません。
(※adodbの必要はないのですが、ExcelVBAのsortのコードを書こうとするとエラーになってしまったので、adodbにしています。)

<仕様>
csvファイルのソートのキーになるのは、「判定区分」の値で昇順に行いたいです。
cs...続きを読む

Aベストアンサー

こんな感じの VBS でどうでしょ。
E:\TMP フォルダ中に test.csv があると仮定しています。
なお、下記はExcelの標準モジュール(Sub モジュール)でも可。
※日付フィールドの書式変更はそちらで行ってください。

Dim cn
Dim rs
Dim xl, bk
Dim i

Set cn = CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.JET.OLEDB.4.0"
.ConnectionString = _
"Data Source=E:\TMP;" _
& "Extended Properties='text;HDR=Yes;" _
& "FMT=Delimited'"
.Open
End With

Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM test.csv order by 判定区分", cn', 0, 1, 1

Set xl = CreateObject("excel.application")
xl.Visible = True
Set bk = xl.Workbooks.Add

For i = 0 To rs.Fields.Count - 1
bk.Sheets(1).Cells(1, i + 1) = rs.Fields(i).Name
Next

bk.Sheets(1).Cells(2, 1).CopyFromRecordset rs
xl.UserControl = True
rs.Close:set rs = Nothing
cn.Close:set cn = Nothing

こんな感じの VBS でどうでしょ。
E:\TMP フォルダ中に test.csv があると仮定しています。
なお、下記はExcelの標準モジュール(Sub モジュール)でも可。
※日付フィールドの書式変更はそちらで行ってください。

Dim cn
Dim rs
Dim xl, bk
Dim i

Set cn = CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.JET.OLEDB.4.0"
.ConnectionString = _
"Data Source=E:\TMP;" _
& "Extended Properties='text;HDR=Yes;" _
...続きを読む

QVBScriptでCSVファイルを読み出したい

現在VBScriptでCSVファイルを1行ずつ読み取って、2次元配列に格納するプログラムを作成しています。
CSVファイルの中身は、サンプルで
shop,price,sales
001,500,700
003,1200,90
024,,18 という並びになっています。
実データは300件くらいです。
1行目のヘッダーを読み飛ばし、2行目のデータから1行ずつ読取、","でsplitを用いてまず1次配列に格納しています。
1次元配列のarrLine(0)=001、(1)=500、(2)=700と入ったデータを
2次元配列arrshopに順次保存?したいのです。
----------------------------------------------
dim strLine '1行ずつ読込んだデータを持つ
dim ntLineNum '行数のカウント
dim arrLine '","で区切った要素を持つ一次元配列
dim arrshop '一次元配列になった要素を2次元配列として格納

Do until .AtEndOfStream
  strLine = .ReadLine
  if 0<>strComp("",Trim(strLine)) then
ntLineNum = intLineNum + 1
  end if
  arrLine = split(strLine , ",")
  arrshop = Array(arrLines,i)
i = i + 1
loop
-----------------------------------------
msgbox arrshop(2)(0) と指定すると「003」出るようにしたいです。
Array関数が上手くないような気もします・・・。
どなたかご教授お願いします(>_<。)

現在VBScriptでCSVファイルを1行ずつ読み取って、2次元配列に格納するプログラムを作成しています。
CSVファイルの中身は、サンプルで
shop,price,sales
001,500,700
003,1200,90
024,,18 という並びになっています。
実データは300件くらいです。
1行目のヘッダーを読み飛ばし、2行目のデータから1行ずつ読取、","でsplitを用いてまず1次配列に格納しています。
1次元配列のarrLine(0)=001、(1)=500、(2)=700と入ったデータを
2次元配列arrshopに順次保存?したいのです。
--------------------------...続きを読む

Aベストアンサー

Arrayのところがおかしいですね。

動くか検証してないですが…
arrshop = Array(arrLines,i)
の代わりに
Redim Preserve arrshop(i+1)
arrshop(i)=arrLines
でやってみてください。
それと最初にiは0か1にでも初期化してから使う事をお勧めします。

QVBScriptで配列のソートをするには?

VBScriptで作成した配列の順番をソートする場合、どのようなコーティングを行えば、実現できるでしょうか?
ソートそのものを実装する関数がありますか?

Aベストアンサー

簡単なものなら
シンプルソート、バブルソート
再起呼び出しなどを使えるレベルならば
マージソート、クイックソート

これらのアルゴリズムの名前で検索をかければ
プログラム例が載っているサイトがみつかりますよ。

Qcsvファイル内にてソートする方法

ご協力お願いします。

あるログデータを取得したcsvファイルを作成しました。しかし、データ量も多く見やすいようにソートをかけたいのですが方法がわかりません。csvファイルの中身は以下のようになっています。
___________________________
| 端末ID | ユーザーID | 日付 | 時間 |
―――――――――――――――――――――――――
| ITD002 | 00000001 |2005/08/22| 11:00 |
―――――――――――――――――――――――――
| ITD002 | 00000003 |2005/08/22| 21:00 |
―――――――――――――――――――――――――
| ITD001 | 00000001 |2005/08/22| 12:00 |
―――――――――――――――――――――――――
| ITD001 | 00000002 |2005/08/22| 18:20 |
―――――――――――――――――――――――――
以上のような中身になっています。レコード量は、もっと多いです。このランダムな順番に取得したレコードを 端末ID(昇順)ユーザーID(昇順)日付(降順)時間(降順)でソートする方法をご教授お願いします。

ご協力お願いします。

あるログデータを取得したcsvファイルを作成しました。しかし、データ量も多く見やすいようにソートをかけたいのですが方法がわかりません。csvファイルの中身は以下のようになっています。
___________________________
| 端末ID | ユーザーID | 日付 | 時間 |
―――――――――――――――――――――――――
| ITD002 | 00000001 |2005/08/22| 11:00 |
―――――――――――――――――――――――――
| ITD002 | 00000003 |2005/08/22| 21:00 |
―――――――――――――――――――――...続きを読む

Aベストアンサー

ODBCドライバーに、テキストドライバーがあるので組み込み、
ソートするクエリを作成して、結果を出力してしまう。

ただし、別ファイルになりますので、どうしても同じファイルで、というなら
出力をワークとして作成後、元ファイルにコピーで上書き&ワーク削除する。

QVBスクリプトでテキストファイルの行数カウント

VBスクリプトでテキストファイルの行数をカウントする
サンプルソースを探しています。
どなたかご存知の方、教えて下さい。

Aベストアンサー

#1 さんの回答も同様なのですが、ズバリなサンプルを探さずに、少しご自分で解いてみてはどうでしょうか?
覚えると簡単ですよ。

VBScript なら他に、
1) FileSystemObject オブジェクトを生成。
2) (1) の OpenTextFile メソッドでテキストファイルを TextStream として開く。
3) (2) で生成された TextStream オブジェクトの ReadAll メソッドでファイルの中身を一気に読み込む。
4) (3) で読み込んだ中身を、改行コードを区切り文字として VBScript の Split 関数で配列を生成。
5) VBScript の UBound 関数を使い、(4) で生成された配列の添え字の最大値を取得する。
6) (4) で生成された配列の添え字は 0 から始まっているので、(5) の結果に 1 を足す。

てなやり方でも取得できますね。

ReadAll メソッド
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/script56/html/jsprotype.asp
Split 関数
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/script56/html/jsprotype.asp
UBound 関数
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/script56/html/jsprotype.asp

#1 さんの回答も同様なのですが、ズバリなサンプルを探さずに、少しご自分で解いてみてはどうでしょうか?
覚えると簡単ですよ。

VBScript なら他に、
1) FileSystemObject オブジェクトを生成。
2) (1) の OpenTextFile メソッドでテキストファイルを TextStream として開く。
3) (2) で生成された TextStream オブジェクトの ReadAll メソッドでファイルの中身を一気に読み込む。
4) (3) で読み込んだ中身を、改行コードを区切り文字として VBScript の Split 関数で配列を生成。
5) VBScript の UBoun...続きを読む

QVBS ファイルマージ処理

特定のDir内、複数ファイルのレコードを全てマージする為、
以下の処理を考えておりますが実現に至っておりません。

Fileがなくなるまで、ループ処理をさせる為、File名
の(1)から(2)へFile名の受け渡し方法が解かりません。
何方か有識者の方、ご教授頂けませんでしょうか
もっと賢くマージが出来るので有りますならば、その方法
を教えて頂けませんでしょうか
※Dir内にFileはユニークなFile名にて、複数個作られます。
※マージに必要なFileだけがDirには作られます。
※マージするFileの順番は問いません。

(1)C:\temp\temp Dir内のFile名を取得
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\temp\temp")
objFile = objFso.GetAbsolutepathname("temp_ini.txt")
Set objOut = objFso.OpenTextFile(objFile, 2, False)
For Each objFile In objFolder.Files
objFilemei = objFile.Name
objOut.Writeline objFilemei
next
※File名の受け渡しがわからず、一旦Fileに書き出してます

(2)Fileが無くなるまで、File内のレコードを全て読込み、マージファイルを作成(予定)
objFile1 = objFso.GetAbsolutepathname("temp_temp.txt")
Set objin = objFso.OpenTextFile("temp_ini.txt",1)
Do Until objin.atendofstream = True
linedata = objin.readline()
loop

説明が悪くてすみませんが、よろしくお願い致します。

特定のDir内、複数ファイルのレコードを全てマージする為、
以下の処理を考えておりますが実現に至っておりません。

Fileがなくなるまで、ループ処理をさせる為、File名
の(1)から(2)へFile名の受け渡し方法が解かりません。
何方か有識者の方、ご教授頂けませんでしょうか
もっと賢くマージが出来るので有りますならば、その方法
を教えて頂けませんでしょうか
※Dir内にFileはユニークなFile名にて、複数個作られます。
※マージに必要なFileだけがDirには作られます。
※マージするFileの順番は問いま...続きを読む

Aベストアンサー

やさしく説明するよりもソースとコメントの方が分かりやすいと思うので。

Option Explicit

'対象フォルダ
Const TRAGET_FOLDER = "C:\temp\temp"

'集計ファイルパス
Const OUTPUT_PATH = "C:\temp\sum.txt"

'FileSystemObject
Dim objFso

'対象ディレクトリ
Dim objFolder

'対象ファイル
Dim objFile

'対象ファイルテキストストリーム
Dim objTS

'出力先ファイルオブジェクト
Dim objOutFile

'カウンタ
Dim i

'FileSystemObject生成
Set objFso = CreateObject("Scripting.FileSystemObject")

'対象ディレクトリを取得
Set objFolder = objFSO.GetFolder(TRAGET_FOLDER)

'出力先ファイルを開く
Set objOutFile = objFso.CreateTextFile(OUTPUT_PATH)

'対象ディレクトリにあるファイル分繰り返し処理
For Each objFile In objFolder.Files

'ファイルを開く
Set objTS = objFile.OpenAsTextStream(1, -2)

'5行スキップ
For i = 1 To 5
'ファイル末尾判別
If Not objTS.AtEndOfStream Then
objTS.SkipLine
End If
Next

'ファイル末尾まで書き出し
Do While objTS.AtEndOfStream <> True
objOutFile.writeLine(objTS.readLine)
Loop

'ファイルを閉じる
objTS.Close

'オブジェクトの解放
Set objTS = Nothing

Next

'出力ファイルを閉じる
objOutFile.Close

'後処理
Set objOutFile = Nothing
Set objFso = Nothing

やさしく説明するよりもソースとコメントの方が分かりやすいと思うので。

Option Explicit

'対象フォルダ
Const TRAGET_FOLDER = "C:\temp\temp"

'集計ファイルパス
Const OUTPUT_PATH = "C:\temp\sum.txt"

'FileSystemObject
Dim objFso

'対象ディレクトリ
Dim objFolder

'対象ファイル
Dim objFile

'対象ファイルテキストストリーム
Dim objTS

'出力先ファイルオブジェクト
Dim objOutFile

'カウンタ
Dim i

'FileSystemObject生成
Set objFso = CreateObject("Scripting...続きを読む

QVBScriptにて、csvファイルから特定のレコードを取得したい

以下のcsvファイルから例えば、「name」列が「aaa」の行を取得するVBScriptを作成したのですが、うまくいきません。ご教授お願いいたします。
---------------
name,id
aaa,1
bbb,2
ccc,3
---------------

作成したVBScriptは以下のものになります。
(SQL文のWhere句に直接、「where name= 'aaa'」と打つとうまくいきますが、変数を指定したいです。)
-------------------------------------------
Option Explicit

Dim objADO
Dim objRS
Dim strName

strName = "aaa"

'ADOオブジェクトを作成
Set objADO = CreateObject("ADODB.Connection")

'ADOを使いCSVファイルを扱う準備(オープン)を行う
objADO.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
"DBQ=C:\sagyou\;" & _
"ReadOnly=1"

'SQLを実行し、当該タスクのデータを抽出します
Set objRS = objADO.Execute("select * from test.csv where name= strName")

'レコードセットをクローズobjRS.Close
objRS.Close

'ADOオブジェクトをクローズ
objADO.Close

以下のcsvファイルから例えば、「name」列が「aaa」の行を取得するVBScriptを作成したのですが、うまくいきません。ご教授お願いいたします。
---------------
name,id
aaa,1
bbb,2
ccc,3
---------------

作成したVBScriptは以下のものになります。
(SQL文のWhere句に直接、「where name= 'aaa'」と打つとうまくいきますが、変数を指定したいです。)
-------------------------------------------
Option Explicit

Dim objADO
Dim objRS
Dim strName

strName = "aaa"

'ADOオブジェクトを...続きを読む

Aベストアンサー

VBA みたいに "" を使うとダメみたいですね。失礼しました。
Set objRS = objADO.Execute("select * from test.csv where name='" & strName & "'")
としてみてください。

QVBSで"をエスケープする文字は?

VBSで"をエスケープする文字はなんでしょうか?

Aベストアンサー

エスケープといった考えが VBSではなかったように思います

"をあらわすには "で括る必要が生じます
たとえば "abc" といった内容なら """abc""" といったリテラルになります
一番外側の "のペアが 文字列としての"になります

"ab"cが欲しいなら """ab""c"
a"bc"が欲しいなら "a""bc"""
a"b"cがほしいなら "a""b""c"
といった具合になります

Qbatである文字列内に特定の文字列が含まれているか確認したい

batファイルの中である変数「abc」の中に「test」という文字が含まれていたら○○を行なうという分岐を作成したいのですが、どのように行なえばよいのでしょうか?

そのまま、ずばりのお答えお待ちしております。

よろしくお願い致します。

Aベストアンサー

大文字小文字を区別しなくていいなら、

if not "%abc:test=%" == "%abc%" echo 含まれていた

区別するなら、

echo %abc% | find "test" >NUL
if not ERRORLEVEL 1 echo 含まれていた

Qコマンドプロンプトの「%1」と「%~1」の違いがわからない

コマンドプロンプトの「%1」と「%~1」の違いがわからない
このサイトにhttp://ykr414.com/dos/bat.html
%~1は「全ての引用句(")を削除して%1を展開する。」とありますがよくわかりません。

%1は入力されたファイルのフルパスだと思っているのですけど。
"%1"=%~1ということでしょうか。

Aベストアンサー

%1は、バッチファイルに指定された「第一引数」です。
バッチファイルに限らず、プログラムを実行するときには引数を指定することができます。
単純に関連づけて実行するとかバッチファイルのアイコンにファイルをにドラッグドロップするとかだと、引数は一つない場合が多いですが、
実際にはショートカットを作ったりコマンドプロンプトから指定するとか、二つ以上の引数を指定することができます。
その際、引数と引数の間はスペースで区切られます。(引数指定全体の文字列を、スペースで区切って各引数に分割する)

一方、例えば、マイドキュメントフォルダ「C:\Documents and Settings\ユーザー名\My Documents」を引数にを指定した場合、そのままだとフォルダ名に空白が入ってるので、
%1=C:\Documents
%2=and
%3=Settings\ユーザー名\My
%4=Documents
と、指定した一つの名前が複数の引数に分断されてしまします。

そこで、こういう場合には、ダブルクオートでファイル名を括ります。
プログラム起動時の引数に 「"C:\Documents and Settings\ユーザー名\My Documents"」
といった感じで、ダブルクオートを付けたものを指定すると、
%1="C:\Documents and Settings\ユーザー名\My Documents"
と、括られた部分がまとめて一つの引数と取り扱われるようになります。
そして、この時%~1は
%~1=C:\Documents and Settings\ユーザー名\My Documents
になります。

%1と%~1の使い分けですが、
引数をこのままファイル名として使う時は、%1をそのまま使えば問題ないのです。
(バッチファイルから別のプログラムを起動するときにファイル指定するとかだったら、
%1を使えば、ダブルクオート込みで渡されるので、そのまま一つの引数としてつかます)

一方、フォルダを指定してそのフォルダ下のファイル名を作る、といった処理をしようとする時には、
ダブルクオートが邪魔なので、そういう時は%~1を使います。
たとえば、指定した引数をフォルダとして、そのフォルダ下の「新規作成データ.txt」ファイルを表すフルパスのファイル名を作りたい場合、

単に
 「%1\新規作成データ.txt」とすると、「"C:\Documents and Settings\ユーザー名\My Documents"\新規作成データ.txt」になってしまいますが、

「"%~1\新規作成データ.txt"」とすれば「"C:\Documents and Settings\ユーザー名\My Documents\新規作成データ.txt"」という、正しくクオートされたファイル名を作ることができます。

%1は、バッチファイルに指定された「第一引数」です。
バッチファイルに限らず、プログラムを実行するときには引数を指定することができます。
単純に関連づけて実行するとかバッチファイルのアイコンにファイルをにドラッグドロップするとかだと、引数は一つない場合が多いですが、
実際にはショートカットを作ったりコマンドプロンプトから指定するとか、二つ以上の引数を指定することができます。
その際、引数と引数の間はスペースで区切られます。(引数指定全体の文字列を、スペースで区切って各引数に分割す...続きを読む


人気Q&Aランキング