こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

vbs csv編集 プログラム

vbsで以下のように編集したいです。
<編集前>
   A     B      C
1 aaa@aaa.jp bbb@bbb.jp ccc@ccc.jp
2       bbb@bbb.jp ccc@ccc.jp
3             ccc@ccc.jp

<編集後>
   A     B      C      D
1 aaa@aaa.jp aaa@aaa.jp bbb@bbb.jp ccc@ccc.jp
2 bbb@bbb.jp       bbb@bbb.jp ccc@ccc.jp
3 ccc@ccc.jp             ccc@ccc.jp

<編集後>
(1)A列に値がある場合は、その値をA列にコピーする。
(2)A列に値がなく、B列に値がある場合は、その値をA列にコピーする。
(3)B列に値がなく、C列に値がある場合は、その値をA列のコピーする
※A、B、C列すべてに値がある場合は、A列の値をA列(編集後)にコピーする。

上記可能でしたら、コードのご教示お願いいたします。

投稿日時 - 2018-12-03 22:45:36

QNo.9564370

すぐに回答ほしいです

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

これから処理したい「csv」ファイルを、プログラムファイルにドラッグ&ドロップしてください(複数可)。

ドラッグ&ドロップしたファイルが、「abc.csv」なら、同じフォルダ内に「abc(Result).csv」という結果ファイルを作成します。

Option Explicit
Dim a, cr, cv, f, i, j, n, wa, so, x
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))
n = so.GetBaseName(wa(i))
Set cv = so.OpenTextFile(wa(i), 1)
Set cr = so.OpenTextFile(f & "\" & n & "(Result).csv", 2, True)
Do Until cv.AtEndOfStream
a = Split(cv.ReadLine, ",")
For j = 0 to UBound(a)
If a(j) <> "" Then
x = a(j)
Exit For
End If
Next
cr.WriteLine x & "," & Join(a, ",")
Loop
cv.Close
cr.Close
Set cv = Nothing
Set cr = Nothing
End If
Next
Set wa = Nothing
Set so = Nothing
MsgBox("Finished!")

簡単な説明です。

基本的には「vbs csv内の一部の値を連結」をお読みください。

For j = 0 to UBound(a)
If a(j) <> "" Then
x = a(j)
Exit For
End If
Next

ここだけが、違います。

「UBound()」は、配列変数の添え字(「()」内の数字)の最大値を返します。

すなわち「a(0) = "a"」、「a(1) = "b"」、「a(2) = "c"」なら、最大値は「2」ですので、「For i = 0 to 2」と記述しているのと同じです。

そして、配列変数に格納された値を1つずつ調べ、初めて空白でない値が見つかると、その値を「x」に入れておきます。

見つかり、それ以上調べてはいけないので、「Exit For」で、「For j = 0 to UBound(a) ~ Next」を抜け出しています。

cr.WriteLine x & "," & Join(a, ",")

「x」+「,」と、元々読み込んだ1行と同じもの(=「Join(a, ",")」)を結果ファイルに書き込んでいます。

投稿日時 - 2018-12-04 19:13:50

補足

ご回答ありがとうございます。
勉強不足で恐縮なのですが、
UBoundのところで、G列からI列のみ対象とする場合はどのような記述になるでしょうか?
試しにFor j = 5 to 7 と記述して実行した結果、上手くいったように見えました。間違いはありますでしょうか?
よろしくお願いいたします。

投稿日時 - 2018-12-05 09:37:53

お礼

ご回答ありがとうございます。
コードの読み取りが苦手な私ですが、
理解しやすかったです。
ありがとうございました。

投稿日時 - 2018-12-05 21:19:27

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

申し訳ございません。

私の説明が悪かったです。

列「G」は、「7」列目です。

しかし、配列変数は「0」から始まるので、「0」からカウントしなければなりません。

すなわち、列「A」が「0」、列「B」が「1」、・・・列「G」は「6」です。

したがって、「For j = 4 to 6」にしてください。

これで、

投稿日時 - 2018-12-05 12:14:29

ANo.3

必ず「G」列まで存在するのでしたら、全く問題ありません。

質問者の環境に合わせて、お使いください。

投稿日時 - 2018-12-05 10:15:32

補足

度々、すみません。
先程のFor j = 5 to 7 と記述して実行した結果ですが、「インデックスが有効範囲にありません」とエラーが出てしまいます。出力結果に関しては問題ないと思われるのですが何が原因と考えられるでしょうか。

投稿日時 - 2018-12-05 11:23:17

ANo.1

ExcelVBAでもできるのに、なぜVBSでやるのか。
>可能でしたら
というほどの課題じゃない。
>ご教示お願いいたします
ここはコードを請け負うコーナーではないと思う。
どこまで質問者が、調べ、考えたかが問題(特に処理ロジック)。丸投げ質問になっている。
ーー
VBSでやる場合は、、OPEN、CLOSE、READ,WRITEに当たる行は、VBSのステーツメント、コマンドに変えれば仕舞い。
 Gogleで「VBS ファイル  入出力」で照会のこと。
 http://neos21.hatenablog.com/entry/2016/03/13/195949 のような記事参照。
ーー
SPLIT関数とJoin関数を活用させてもらった例。VBSでも使える。
Sub test01()
Dim x As Variant
Open "C:\Users\XXX\ドキュメント\Documents\質問例1.csv" For Input As #1
Open "C:\Users\XXX\ドキュメント\Documents\質問例1B.csv" For Output As #2
'---
While Not EOF(1)
Line Input #1, s
s = "," & s '先頭列を1 列追加に相当
x = Split(s, ",")  '配列に展開
If x(1) = "" Then '2列目(元の1列目)が空白なら
For i = 2 To UBound(x)
If x(i) <> "" Then '非空白列まで順次探して
x(0) = x(i)
s = Join(x, ",")
Exit For
End If
Next
Else
x(0) = x(1)
s = Join(x, ",")
End If
Print #2, Join(x, ",")
Wend
'-----
Close #1
Close #2
End Sub
ーーー
結果
Excelシートで確認。A-D列
aaa@aaa.jpaaa@aaa.jpbbb@bbb.jpccc@ccc.jp
bbb@bbb.jp     bbb@bbb.jpccc@ccc.jp
ccc@ccc.jp          ccc@ccc.jp

投稿日時 - 2018-12-04 16:02:14

あなたにオススメの質問