エクセルのバッチ処理について教えてください。


同じ項目のcsvファイルが数千個あります。
すべてのファイルをHの列で単一化し指定のフォルダに保存しなおします。(ファイル名は元のファイル名と同じでOK)
単一化にはExcel2007の「重複削除」を使用しています。

これらの作業をバッチ処理する方法がございましたらご教授ください。

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

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2011/05/10 13:04:06
  • 終了:2011/05/17 13:05:04

ベストアンサー

id:a-kuma3 No.4

a-kuma3回答回数4469ベストアンサー獲得回数18442011/05/10 17:10:13

ポイント20pt

WSH から Excel を使ってあげれば、バッチ処理ができます。

' 対象のファイルが入っているディレクトリ
target_dir = "D:\test"

set fso = WScript.CreateObject("Scripting.FileSystemObject")
set folder = fso.GetFolder(target_dir)

set xlApp = CreateObject("Excel.Application")

for each file In folder.Files

    f = target_dir & "\" & file.Name
    WScript.Echo "--> " & f    ' ファイル名をコンソールに出す (要らないか?)

    set xlBook = xlApp.Workbooks.Open(f)
    set xlSheet = xlBook.Sheets(1)

    ' A~H 列の範囲で、H 列で重複削除する
    xlSheet.Range("A:H").RemoveDuplicates 8, 2  '8: H列, 2: xlNo
 
    xlApp.DisplayAlerts = False
    xlBook.Save
    xlBook.Close
    xlApp.DisplayAlerts = True    

    set xlSheet = Nothing
    set xlBook = Nothing
next


set xlApp = Nothing

上記の内容を、convert.vbs というような名前のテキストファイルに保存しておいて、

コマンドプロンプトから、以下のように指定して実行。

d> cscript convert.vbs

格納先のディレクトリには、変換対象の CSV ファイルしか置いてないものとしています。

id:uluru5

おおおおお!ありがとうごいます!!動きました!

ただ、1ファイルごとに「OK」を押さなければいけないのですが、そこを省くことはできますでしょうか?

2011/05/10 19:32:02

その他の回答(4件)

id:taknt No.1

きゃづみぃ回答回数13538ベストアンサー獲得回数11982011/05/10 14:05:37

ポイント20pt

バッチファイルでは 難しいですね。

以下のVBAで やってみたらいいでしょう。

なお 項目の1行目は 見出しとして扱ってます(重複チェックの対象外)

Sub main()
Dim p As String
'対象フォルダを指定してください。
'このフォルダに この実行用のブックは 入れないでください。

p = "C:\test\"

'処理対象となる拡張子を指定して 呼び出します。
Call jikkou(p, "csv")

End Sub



Sub jikkou(p As String, s As String)
f = Dir(p & "*." & s, vbNormal)

Do While f <> ""
    Set w = Workbooks.Open(Filename:=p & f, UpdateLinks:=False, ReadOnly:=False)
    
    With w.Sheets(1)
        .Columns("I:I").Insert Shift:=xlToRight
        .Columns("H:H").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=.Range("I1"), Unique:=True
        .Columns("H:H").Delete Shift:=xlToLeft
    End With
     
    Application.DisplayAlerts = False
    w.Save
    w.Close
    Application.DisplayAlerts = True    
    f = Dir
Loop


End Sub

id:uluru5

ありがとうございます!

しかし、これを実行する方法がわかりません。。。

なお、1行目に見出しはございません。

実行方法をご教授いただけると幸いです。

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

2011/05/10 15:08:34
id:fonya3 No.2

fonya3回答回数238ベストアンサー獲得回数102011/05/10 14:28:19

ポイント20pt

答えになっていませんが、バッチ処理にExcelは不向きじゃないでしょうか?

Excel VBAでやろうとすると、フォアグラウンドの処理能力を占有してしまって

固まってしまうので、通常私はそのようなときはVBScriptかPerlなどでちょいと

書いて処理してます。VBScriptならVBAと同じように書けると思いますよ。

ファイルオブジェクトでフォルダを開く

 中にあるCSVファイルを順番に開いて処理する

  CSVファイルの先頭から一行ずつ読み込む

   Hの列の値で連想配列が有効かチェックする

    有効なら処理をパス

    無効なら連想配列にセットして、結果書き出しようの変数に行データを入れる

  ひとつのCSVファイルを読み終わったら、

   元ファイルをリネーム

   結果変数をファイルに書き出す

   結果変数をクリアー

   連想配列をクリアー

 次のファイルを処理

処理が完了したらフォルダを閉じる


とか、こんな感じの処理のながれでしょうか。

すいませんが、ソースを書いてる時間が無いので、考え方だけです。

id:uluru5

ありがとうございます。

2011/05/10 15:09:09
id:taknt No.3

きゃづみぃ回答回数13538ベストアンサー獲得回数11982011/05/10 16:05:38

ポイント20pt

http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_01_2007.html

マクロを何か記録してから そのソースと 以下のソースに置換してもらえればいいです。

見出しがないバージョンを作成しました。

Sub main()
Dim p As String
'対象フォルダを指定してください。
'このフォルダに この実行用のブックは 入れないでください。
p = "C:\test\"

'処理対象となる拡張子を指定して 呼び出します。
Call jikkou(p, "csv")

End Sub



Sub jikkou(p As String, s As String)
f = Dir(p & "*." & s, vbNormal)

Do While f <> ""
    Set w = Workbooks.Open(Filename:=p & f, UpdateLinks:=False, ReadOnly:=False)
    
    With w.Sheets(1)
        .Range("H1").Insert Shift:=xlDown
        .Range("H1") = "見出し"
        .Columns("I:I").Insert Shift:=xlToRight
        .Columns("H:H").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=.Range("I1"), Unique:=True
        .Columns("H:H").Delete Shift:=xlToLeft
        .Range("H1").Delete Shift:=xlUp
    End With
     
    Application.DisplayAlerts = False
    w.Save
    w.Close
    
    f = Dir
Loop

<||
id:uluru5

修正版ありがとうございました!

また、マクロの実行方法もありがとうございました。

しかし、何かしら作成したマクロは動くのですが、ソースを置き換えるとピクリともしません。。。

何か抜けている手順があるのでしょうか。

ソースを見る限り、マクロを実行すると「対象フォルダを指定してください。」というのが現れる感じですが、何も現れません。

2011/05/10 16:29:17
id:a-kuma3 No.4

a-kuma3回答回数4469ベストアンサー獲得回数18442011/05/10 17:10:13ここでベストアンサー

ポイント20pt

WSH から Excel を使ってあげれば、バッチ処理ができます。

' 対象のファイルが入っているディレクトリ
target_dir = "D:\test"

set fso = WScript.CreateObject("Scripting.FileSystemObject")
set folder = fso.GetFolder(target_dir)

set xlApp = CreateObject("Excel.Application")

for each file In folder.Files

    f = target_dir & "\" & file.Name
    WScript.Echo "--> " & f    ' ファイル名をコンソールに出す (要らないか?)

    set xlBook = xlApp.Workbooks.Open(f)
    set xlSheet = xlBook.Sheets(1)

    ' A~H 列の範囲で、H 列で重複削除する
    xlSheet.Range("A:H").RemoveDuplicates 8, 2  '8: H列, 2: xlNo
 
    xlApp.DisplayAlerts = False
    xlBook.Save
    xlBook.Close
    xlApp.DisplayAlerts = True    

    set xlSheet = Nothing
    set xlBook = Nothing
next


set xlApp = Nothing

上記の内容を、convert.vbs というような名前のテキストファイルに保存しておいて、

コマンドプロンプトから、以下のように指定して実行。

d> cscript convert.vbs

格納先のディレクトリには、変換対象の CSV ファイルしか置いてないものとしています。

id:uluru5

おおおおお!ありがとうごいます!!動きました!

ただ、1ファイルごとに「OK」を押さなければいけないのですが、そこを省くことはできますでしょうか?

2011/05/10 19:32:02
id:a-kuma3 No.5

a-kuma3回答回数4469ベストアンサー獲得回数18442011/05/10 22:42:29

ポイント20pt

ただ、1ファイルごとに「OK」を押さなければいけないのですが、そこを省くことはできますでしょうか?

あらっ、出さないようにしたつもりなんですけど。

一応、手元で動作させてみて、保存の問い合わせが出ないことは確認したんですけどね。


xlApp.DisplayAlerts = False

↑を入れることで、保存のときの問い合わせをしないようにしてます。

保存の前後で、True を設定してるのは、保存以外のときに、予期せぬ問い合わせを消してしまわないようにしてるつもりです。

そのままコピペしてると思うんですが、コードを確認してみてください。

id:uluru5

ありがとうございます。

とりあえずやってみます。。

2011/05/11 10:10:03
  • id:taknt
    >ソースを見る限り、マクロを実行すると「対象フォルダを指定してください。」というのが現れる感じですが、何も現れません。

    これは コメントです。
    直接、そこのパスを変更してください ということです。

    たぶん、該当するファイルがないから 何も 起こらないと思います。

    ちなみに 実行させるのは main です。
    (ちょっと まぎらわしかったですね)

  • id:uluru5
    a-kuma3さま

    WScript.Echo "--> " & f ' ファイル名をコンソールに出す (要らないか?)

    をコメントアウトしたらできました!!!

    ありがとうございました。
  • id:a-kuma3
    あー、ごめんなさい。
    数千もファイルがあるから、どこまで進んでるか見えないと不安かな、とか、
    数が多いからこそ、余計な出力かな、とか、思いながら書いてしまいました。

    役に立てて、よかった :-)
  • id:uluru5
    H列がすべてブランクのデータもありまして、その場合エラーが出て止まってしまいましたが、
    1行目に「On Error Resume Next」を入れることでスムーズに進めることが出来ました。

    H列がブランクのデータを一覧にしたいのですが、ご教授いただけると助かります。
  • id:a-kuma3
    No.4 の回答で晒したコードだと、H列が全てブランクの CSV でもエラーにならないんですけどね。


    http://www.atmarkit.co.jp/fwin2k/tutor/cformwsh09/cformwsh09_02.html
    ↑のように、on error resume で、with を入れて、エラーが出た CSV のファイル名をどこかに吐き出しておく、というのではどうでしょう?
  • id:uluru5
    ご回答ありがとうございます!
    サイトみてやってみます!

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません