• ベストアンサー

vbcript csvファイルの内容変更

下記の変更できるコードのご教示頂けますでしょうか。 <実行前> A列 B列  C列 田中 更新  北海道 佐藤    沖縄 <実行後> A列 B列  C列 田中 更新  北海道 佐藤 新規  沖縄 <編集内容> B列に空白があった場合、「新規」と出力する できれば、下記URLのベストアンサーの方のように Buf(i)を利用するようなコードでご教示頂けると嬉しいです。(不可能ならばほかの方法でお願いします) https://okwave.jp/qa/q9552634.html

質問者が選んだベストアンサー

  • ベストアンサー
  • watabe007
  • ベストアンサー率62% (476/760)
回答No.5

>コードのv(0)~v(2)がA,B,C列だと認識しています。 その通りです。 >質問に記載している表よりも列も行も大量にあるため B列のデータの有無を確認するので2列以上あれば大丈夫です。 行も10000行でテストしましたが問題なく処理できました。 Option Explicit Dim objArgs, Fso, Arg, buf, FilePath, i, v Set objArgs = WScript.Arguments Set Fso = CreateObject("Scripting.FileSystemObject") If objArgs.Count < 1 Then WScript.Quit For Each Arg In objArgs FilePath = Arg With Fso.OpenTextFile(FilePath) buf = .ReadAll .Close End With buf = Split(buf, vbCrLf) For i = 0 To Ubound(buf) v = Split(buf(i), ",") If Ubound(v) < 2 Then ElseIf v(1) = "" Then v(1) = "新規" buf(i) = Join(v, ",") End If Next buf = Join(buf, vbCrLf) With FSO.OpenTextFile(FilePath, 2) .Write buf .Close End With Next MsgBox "終わり"

tyarutiru
質問者

お礼

何回もご回答していただき、お手数をかけしました。ご教示頂きました最新のコードのお陰でうまくいきました。 ありがとうございました!

その他の回答 (4)

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.4

ドラッグ&ドロップしたファイルと同じフォルダに、いったん、「Dummy.csv」ファイルを作成し、そこに結果を書き込み、最後に元ファイルを削除して、「Dummy.csv」ファイルを元ファイルと同じファイル名にしています。 Option Explicit Dim a, cv, dm, f, i, m, n, so, wa Set so = CreateObject("Scripting.FileSystemObject") Set wa = WScript.Arguments For i = 0 to wa.Count - 1 If LCase(so.GetExtensionName(wa(i))) = "csv" Then f = so.GetParentFolderName(wa(i)) Set cv = so.OpenTextFile(wa(i), 1) Set dm = so.OpenTextFile(f & "\Dummy.csv", 2, True) Do Until cv.AtEndOfStream a = Split(cv.ReadLine, ",") If a(1) = "" Then a(1) = "新規" End If dm.WriteLine Join(a, ",") Loop cv.Close dm.Close Set cv = Nothing Set dm = Nothing n = so.GetFileName(wa(i)) so.DeleteFile wa(i), True Set m = so.GetFile(f & "\Dummy.csv") m.Name = n End If Next Set wa = Nothing Set so = Nothing MsgBox("Finished!") 簡単な説明です。 Option Explicit 「厳密に」とか「明確に」というような意味で、このオプションを設定すると、変数は、その使用の前に、必ず、「Dim」等によって宣言しておかなければなりません。 Set so = CreateObject("Scripting.FileSystemObject") ファイルやフォルダ、テキストファイルを扱う「Windows」の機能を読み込んでいます。 Set wa = WScript.Arguments ドラッグ&ドロップされるのを待っています。 For i = 0 to wa.Count - 1 ドラッグ&ドロップされたファイルの数だけ処理。 If LCase(so.GetExtensionName(wa(i))) = "csv" Then 「LCase()」は、英字を小文字にしますので、「Csv」や「CSV」も「csv」になります。 「so.GetExtensionName()」は「Scripting.FileSystemObject」の機能を使って(頭の「so.」)、拡張子を取得します。 したがって、ここは「もし拡張子がcsvなら」となります。 f = so.GetParentFolderName(wa(i)) ドラッグ&ドロップされたファイルが存在するフォルダを調べています。 Set cv = so.OpenTextFile(wa(i), 1) 「読み込み専用」(=「1」)で開いています。 Set dm = so.OpenTextFile(f & "\Dummy.csv", 2, True) 同じフォルダ内に「Dummy.csv」ファイルを、「書き込み専用」(=「2」)で、「新規作成を許可」(=「True」)しています。 Do Until cv.AtEndOfStream ファイルの終端まで処理。 a = Split(cv.ReadLine, ",") 1行読み込み、区切り記号を使って配列変数に格納しています。 「Split()」は、配列変数に格納する関数です。 今回は「csv」ファイルということで、区切り記号は「,」ですから「Split(x, ",")」というように「,」を区切り記号として読み込みます。 そして、読み込んだ1行が、たとえば「a,b,c」の場合、「a(0) = "a"」、「a(1) = "b"」、「a(2) = "c"」となります。 If a(1) = "" Then a(1) = "新規" End If 2番目の項目が「空白」なら2番目の中身を「新規」にしています。 dm.WriteLine Join(a, ",") 「Dummy.csv」に書き出していますが、「Join()」は、「Split()」と逆のことをします。 すなわち「a(0) = "a"」、「a(1) = "b"」、「a(2) = "c"」なら「Join(a, ",")」で、「a,b,c」とします。 Loop を、ファイルの終端まで繰り返しています。 cv.Close dm.Close Set cv = Nothing Set dm = Nothing 両ファイルを閉じています。 n = so.GetFileName(wa(i)) ドラッグ&ドロップされた方のファイルのファイル名を調べています。 so.DeleteFile wa(i), True 削除しています。 Set m = so.GetFile(f & "\Dummy.csv") 「Dummy.csv」ファイルのファイル名を変更するためにファイルをゲット(「取得」)しています。 m.Name = n ファイル名を、元のドラッグ&ドロップされたファイルと同じにしています。 End If Next を、ドラッグ&ドロップされたファイルの数だけ繰り返しています。 Set wa = Nothing Set so = Nothing 「Set ~」で使った変数は、その使用後「Nothing」で解放しておきます。 MsgBox("Finished!") いつ終わったか、分かりにくいので、最後に「Finished!」と表示しています。

  • watabe007
  • ベストアンサー率62% (476/760)
回答No.3

回答No.2 で可読性を良くするのに 全角文字で段落を付けましたが、そのままコピーするとエラーが出ますので 全角文字を省いてください。 Option Explicit Dim objArgs, Fso, Arg, buf, FilePath, i, v Set objArgs = WScript.Arguments Set Fso = CreateObject("Scripting.FileSystemObject") If objArgs.Count < 1 Then WScript.Quit For Each Arg In objArgs FilePath = Arg With Fso.OpenTextFile(FilePath) buf = .ReadAll .Close End With buf = Split(buf, vbCrLf) For i = 0 To Ubound(buf) v = Split(buf(i), ",") If Ubound(v) <> 2 Then ElseIf v(1) = "" Then buf(i) = v(0) & "," & "新規" & "," & v(2) End If Next buf = Join(buf, vbCrLf) With FSO.OpenTextFile(FilePath, 2) .Write buf .Close End With Next MsgBox "終わり"

tyarutiru
質問者

補足

ご回答ありがとうございます。 URL先のコードを利用したご教示ありがとうごさいます。 説明不足で恐縮なのですが、コードのv(0)~v(2)がA,B,C列だと認識しています。 ただ、csvファイルの内容としては、質問に記載している表よりも列も行も大量にあるため、こちらのコードでは難しいと感じました。 大変お手数ではございますが、上記を踏まえたコードのご教示は可能でしょうか。

  • watabe007
  • ベストアンサー率62% (476/760)
回答No.2

一部変更しました。 Option Explicit Dim objArgs, Fso, Arg, buf, FilePath, i, v Set objArgs = WScript.Arguments Set Fso = CreateObject("Scripting.FileSystemObject") If objArgs.Count < 1 Then WScript.Quit For Each Arg In objArgs   FilePath = Arg   With Fso.OpenTextFile(FilePath)     buf = .ReadAll     .Close   End With   buf = Split(buf, vbCrLf)   For i = 0 To Ubound(buf)     v = Split(buf(i), ",")     If Ubound(v) <> 2 Then     ElseIf v(1) = "" Then       buf(i) = v(0) & "," & "新規" & "," & v(2)     End If   Next   buf = Join(buf, vbCrLf)   With FSO.OpenTextFile(FilePath, 2)     .Write buf     .Close   End With Next MsgBox "終わり"

  • watabe007
  • ベストアンサー率62% (476/760)
回答No.1

こんばんは、これでどうでしょうか Option Explicit Dim objArgs, Fso, Arg, buf, FilePath, i, v Set objArgs = WScript.Arguments Set Fso = CreateObject("Scripting.FileSystemObject") If objArgs.Count < 1 Then WScript.Quit For Each Arg In objArgs FilePath = Arg With Fso.OpenTextFile(FilePath) buf = .ReadAll .Close End With buf = Split(buf, vbCrLf) For i = 0 To Ubound(buf) v = Split(buf(i), ",") If buf(i) = "" Then ElseIf v(1) = "" Then buf(i) = v(0) & "," & "新規" & "," & v(2) End If Next buf = Join(buf, vbCrLf) With FSO.OpenTextFile(FilePath, 2) .Write buf .Close End With Next MsgBox "終わり"

関連するQ&A