プロが教える店舗&オフィスのセキュリティ対策術

以下のコードは、あるルートフォルダにトップページ"TOP.html"をつくり(または上書きし)、各階層のフォルダの中に存在する拡張子がabc(仮称)のファイルと同じ名前のhtmlファイルを、abcファイルと同じフォルダに同じ数だけつくり(または上書きし)、トップページにその作成したすべてのhtmlファイルへのリンクを表示させる、という構想で作成中のVBSなのですが(具体的な数値等は"****"としました)、これを実行すると「●(マル)」と書いた55行目のところでエラー「オブジェクト型の変数は定義されていません」となってしまいます。このエラーをどのように対処すればよいかを教えていただければと思います。
私はExcelのVBAは多少の経験がありますが、VBScriptを書いたのはこれが初めてで、HTMLも未経験です。14・15行目の呼び出し方はこれでいいのかどうかも不安です。よろしくお願いします。

Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set CurFolder = fso.GetFolder(".")
Call CreatePages1(CurFolder, "*.abc", files)

Set outFileStream = Nothing
Set CurFolder = Nothing
Set fso = Nothing

'サブフォルダへの処理
Public Sub SearchSubFolder1(ByVal folder)
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set folder2 = fso.GetFolder(folder.Path)
For Each folder2 In folder.SubFolders
Call CreatePages1(folder2, searchPattern, files)
'再帰呼び出し
Call SearchSubFolder1(folder2)
Next
Set fso = Nothing
End Sub

'htmlファイル作成
Public Sub CreatePages1(ByVal folder, ByVal searchPattern, ByRef files)
Set fso = WScript.CreateObject("Scripting.FileSystemObject")

'トップページを途中まで作成する。
Set outFileStream = fso.CreateTextFile(folder.Path & "\TOP.html", True)
outFileStream.WriteLine "<HTML>"
outFileStream.WriteLine "<HEAD>"
outFileStream.WriteLine "<TITLE>Viewer</TITLE>"
outFileStream.WriteLine "</HEAD>"
outFileStream.WriteLine "<BODY>"

'各htmlファイルを作成する。
For Each fs In folder.Files
Set outFileStream = fso.CreateTextFile(folder.Path & "\" & Left(fs.Name, Len(fs.Name) - Len(Ext)-1) & ".html", True)
outFileStream.WriteLine "<HTML>"
outFileStream.WriteLine "<HEAD>"
outFileStream.WriteLine "<TITLE>Browser</TITLE>"
outFileStream.WriteLine "</HEAD>"
outFileStream.WriteLine "<BODY>"
outFileStream.WriteLine "<OBJECT ID=""Browser1"" WIDTH=**** HEIGHT=**** CLASSID=""CLSID:****"">"
outFileStream.WriteLine "<PARAM NAME=""_Version"" VALUE=""*****"">"
outFileStream.WriteLine "<PARAM NAME=""_ExtentX"" VALUE=""*****"">"
outFileStream.WriteLine "<PARAM NAME=""_ExtentY"" VALUE=""*****"">"
outFileStream.WriteLine "<PARAM NAME=""_StockProps"" VALUE=""*****"">"
outFileStream.WriteLine "<PARAM NAME=""FileName"" VALUE=""" & folder.Path & "\" & fs.Name & """>"
outFileStream.WriteLine "</OBJECT>"
outFileStream.WriteLine "</BODY>"
outFileStream.WriteLine "</HTML>"
outFileStream.Close()

'トップページの続きを作成する。
Ext = fso.GetExtensionName(fs.Name)
If LCase(Ext) = "html" Then
●(マル) outFileStream.WriteLine "<a href=""" & folder.Path & "\" & fs.Name & """>" & Left(fs.Name, Len(fs.Name) - Len(Ext)-1) & "</a><br>"
End If
Next
outFileStream.WriteLine "</BODY>"
outFileStream.WriteLine "</HTML>"
outFileStream.Close()

'サブフォルダへの処理。
Set fp = fso.GetFolder(folder.Path)
Call SearchSubFolder1(fp)

End Sub

A 回答 (2件)

試してませんが、ざっと見たところ、、、


50行目で outFileStream を Close() しちゃってませんか?
というか outFileStream が途中で別のファイルを参照しちゃってますよね。

Public Sub Createpages1 では 26行目で outFileStream で Top.html を参照させてますが、34行目から始まる For Each 内でそのほかの html ファイルを参照させちゃってますよね。
だからもし仮に 54行目の If の条件によって 55行目の処理が一度もなされないまま For Each ~ Next が完全に終了し、続いて 58行目から outFileStream (開発者の希望では Top.html を参照していてほしいのだろう) に書き込もうとしていますが、この時すでに outFileStream は For Each 内で別のファイルを参照して Close した後なので、ここでも同様のエラーが出るだろうと思います。

解決策ですが、For Each 内の outFileStream を別の名前の変数にするべきでしょう。

あと、Createpages1 の引数 folder と files は FileSystemObject の Folder オブジェクトと Files プロパティーと同じ名前なので別の名前にしたほうがいいと思います。
私なら
Public Sub CreatePages1(ByVal aFolder, ByVal aSearchPattern, ByRef aFiles)
みたいに引数名の頭に a を付けます。

あとは、、、変数の宣言を必ず行うようにしてます。
そのためファイルの先頭に Option Explicit を付けるようにしています。
これでタイプミスによる変数の自動作成を防げます。

Public Sub CreatePages1(ByVal aFolder, ByVal aSearchPattern, ByRef aFiles)
 Dim fso ' FileSystemObject オブジェクト
 Set fso = CreateObject(略)
 Dim topHtmlTS ' Top.html を参照する TextStream オブジェクト
 Set topHtmlTS = fso.略

 途中略

 Dim fileItem ' File オブジェクト
 For Each fs In aFolder.Files
  Dim otherHtmlTS ' 各 HTML を参照する TextStream オブジェクト
  Set otherHtmlTS = fso.略
  略
  otherHtmlTS.Close()

  If LCase(Ext) = "html" Then
   topHtmlTS.WriteLine 略
  End If
 Next
 topHtmlTS.WriteLine 略
 topHtmlTS.Close

 Dim currentFolder ' 現在のフォルダーを参照する Folder オブジェクト
 Set currentFolder = fso.GetFolder(aFolder.Path)
 Call SearchSubFolder1(currentFolder)
End Sub

あと、VBScript のデバッグは難しいものがあるので、私は最初に Excel の VBEditor 等でソースを書いてステップ実行のデバッグを行ったりしてます。
その際、コードの開始部分も Sub Start() みたいなプロシージャに入れ込んで作ります。(VBScript と VBA の違い)
デバッグが終わったらテキスト ファイルにコピペして、処理開始部分をプロシージャを取っ払って云々の作業をして終了。

後は有料のソフトになりますが VbsEdit というソフトもステップ実行のデバッグができます。
お金を払わなければ起動時にダイアログが出たり、デバッグ時に嫌がらせをされるぐらいで、基本的なことはすべてできます。
インテリセンスも付いているので便利です。
私も無料のまま使ってます。
    • good
    • 0
この回答へのお礼

いろいろ教えていただき、ありがとうございます。
非常に感謝しております。
明日また仕事の合間にじっくりやってみます。

お礼日時:2010/02/09 22:12

エラーになっている原因ではないかもしれませんが、


outFileStream.WriteLine
の前で
outFileStream.Close
としているのはマズイと思います。
    • good
    • 0

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