牛、豚、鶏、どれか一つ食べられなくなるとしたら?

フォルダAの中に以下のファイルがあります。
 ・1.txt
 ・2.txt
  ・
  ・
  ・
 ・10.txt
これを全て連結させたsum.txtを出力として同じフォルダに入れたいと考えています。
ファイル名を取得してフォルダの中の上から順番にsum.txtへ書き込んでいけばいいのはわかるんですが
どのようにプログラムで書いていいのかわかりません。
特にループさせるところがわかりません。
(初心者ですいません)

プログラム例をご教授いただければありがたいです。
また、そういった内容を勉強できるサイトがあれば紹介していただけるとありがたいです。

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

A 回答 (4件)

ANo.3お礼への回答です。



>サンプルに書いてもらったものだと
>出力が2回繰り返されてしまうのは何ででしょうか?

ANo.2、ANo.3のコードでは入力フォルダと同じフォルダにtxtファイルを出力すると、それも連結してしまいます。そのため2回繰り返されたりすることがあります。これを解決するには、別のフォルダに出力するか、出力ファイルを連結から除外するようにすればよいでしょう。

さて、どうしますか?
 :
(しばらく考察)
 :
どうしても同じフォルダに出力したい場合、出力ファイルを連結から除外する簡単な方法は、ANo.3のコードのIfに条件を追加することでしょう。例えば、

If (LCase(fso.GetExtensionName(fn))="txt")And(fn.Name<>"sum.txt") Then

これは美しくないですね…。出力ファイルを作る前にFilesコレクションからファイル名を配列などに取り出し、必要ならANo.2で触れた並べ替えを行ってから連結すると美しいと思います。
    • good
    • 0

ANo.2お礼への回答です。



>このvbsファイルがあるローカルフォルダという指定方法はどうしたらよいのでしょうか?

WScript.ScriptFullNameで実行中のスクリプトのパスが求まりますので、それを使います。なお、vbsファイルを一緒に置くため拡張子txtのみ取り出すようにする必要があります。コードは例えば下記のようです。

Option Explicit
Const OutFileName = "C:\Out\sum.txt"
Const ForReading = 1, ForWriting = 2
Dim fso, f, fc, fn, InFile, OutFile
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(fso.GetParentFolderName(WScript.ScriptFullName))
Set fc = f.Files
Set OutFile = fso.OpenTextFile(OutFileName, ForWriting, true)
For Each fn in fc
If LCase(fso.GetExtensionName(fn))="txt" Then
Set InFile = fso.OpenTextFile(fn, ForReading)
OutFile.Write(InFile.ReadAll())
InFile.Close()
End If
Next
OutFile.Close()
WScript.Echo "連結が終わりました。"

-----
WScript.exeで実行するものとして、入力フォルダ指定とスクリプト起動の方法をいくつか考察しましたので、ついでにアドバイス申し上げます。

(1)ScriptFullNameから実行中のフォルダのパスを求める。フォルダ内にvbsファイルを置いてダブルクリック。
 上の方法ですね。もしフォルダが複数だとvbsファイルを複数置くことになり保守が面倒です。

(2)フォルダ名をArgumentsから求める。デスクトップなどにvbsを置いておき、フォルダをドラッグ&ドロップする。
 私は好んで使っています。頻繁に使うならお奨めです!

(3)フォルダ名をArgumentsから求める。上のバリエーションで、SendToフォルダにvbsを置いておき、フォルダを右クリックして「送る」。
 私は好んで使っています。たまに使うならお奨めです!

(4)BrowseForFolderでフォルダツリーからフォルダを選択する。適当なところにvbsを置いてダブルクリック。
 キー入力が不要でGUIらしいインタフェース。

(5)InputBoxでフォルダのパスをキー入力する。適当なところにvbsを置いてダブルクリック。
 InputBoxに全て入力すると面倒。デフォルトを表示して一部書き換えにすれば便利かも。

なお、(2)(3)(4)(5)の方法ではvbsファイルでなくショートカットを置いてもよいです。
    • good
    • 0
この回答へのお礼

アドバイスありがとうございました!
もう少し勉強してみます。

サンプルに書いてもらったものだと
出力が2回繰り返されてしまうのは何ででしょうか?

お礼日時:2008/01/15 00:22

ファイル名や個数がわからないのでしたら、WSHドキュメントのFilesコレクションのサンプル等から大筋として下記のようなコードが考えられます。

【同じフォルダにはできませんが】ご参考まで。

なお、Windows XP Pro SP2で試したところ、連結の順番が1.txt, 10.txt, 2.txt, 3.txt,…になりました。1.txt, 2.txt, 3.txt,…10.txtの順番にするにはファイル名を取り出して並べ替えてから連結する必要があります。そもそもFilesコレクションからの取り出し順は規定されていないようなので必須の処理かもしれません(?)。

実用向けの改善点としては、入力ファイルが巨大でしたらReadAllではなく1行ずつ連結するとか、拡張子txtのみ取り出すようにするとか、出力ファイルの上書きを確認するとか、あるいは出力ファイル名に日付や時刻を含めるとか。

Option Explicit
Const InFolder = "C:\In"
Const OutFileName = "C:\Out\sum.txt"
Const ForReading = 1, ForWriting = 2
Dim fso, f, fc, fn, InFile, OutFile
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(InFolder)
Set fc = f.Files
Set OutFile = fso.OpenTextFile(OutFileName, ForWriting, true)
For Each fn in fc
Set InFile = fso.OpenTextFile(fn, ForReading)
OutFile.Write(InFile.ReadAll())
InFile.Close()
Next
OutFile.Close()
WScript.Echo "連結が終わりました。"
    • good
    • 0
この回答へのお礼

回答ありがとうございます!

できましたが、
Const InFolder = "C:\In"
を指定しないで、このvbsファイルがあるローカルフォルダという指定方法はどうしたらよいのでしょうか?

お礼日時:2008/01/14 07:28

単純連結ならDOSのコマンドでやれば1行で済むんじゃないかと。

つまりループさせる必要がありません。

Set wShell = CreateObject("WScript.Shell")
Set oExec = wShell.Exec("cmd.exe /c copy c:\1.txt + c:\2.txt + c:\3.txt c:\all.txt")
MsgBox oExec.StdOut.ReadAll()

この程度なら基礎知識だけなので、特にどこかで勉強するというほどのものでもないですが、まずは基本的なことをさらっと抑えておけばよいんじゃないんですかね。後は引っかかる度に個別で検索すれば。
http://www.google.com/search?num=50&hl=ja&q=WSH% …
    • good
    • 1
この回答へのお礼

回答ありがとうございます!

こういう方法もあるんですね!
望んでいるものは出力できました。
他のプログラムにも応用させていただきます。

お礼日時:2008/01/14 07:29

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

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


おすすめ情報