質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.06%

[VBS]なぜだろうか...

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,423

BeatStar

score 1781

VBScriptでファイル圧縮の 1050YENさんのアンサーを元に組んでみました。

( zipファイルを圧縮するプログラムが欲しかったので... )

URLでは zipファイル名は決め打ちですので、コマンドラインから

$CScript.exe CompressZip.vbs compressed1.zip file1.txt ...

と打てば compressed1.zipに...という風に汎用性を持たせるために

コマンドライン引数として受け取るとします。

Option Explicit


'#################################################
' ENTRY-POINT
'#################################################

Dim fs, sh

Set fs = CreateObject( "Scripting.FileSystemObject" )
Set sh = CreateObject( "Shell.Application" )

WScript.Quit MakeZip( WScript.Arguments )



'#################################################
' 関数: 基本の実行部
'#################################################
Private Function MakeZip( params )
                 ' パラメータチェック
                 If Not CheckParams( params ) Then
                     MakeZip = -1
                     Exit Function
                 End If

                 ' ZIPファイル作成メイン
                 If Not CreateZip( WScript.Arguments(0), WScript.Arguments ) Then
                     MakeZip = -3
                     Exit Function
                 End If

                 ' ここまで来たら正常終了
                 MakeZip = 0
End Function



'#################################################
' 関数: 引数チェック
'#################################################
Private Function CheckParams( params )
                  If params.Count > 1 Then
                       CheckParams = True
                  Else
                       CheckParams = False
                  End If
End Function



'#################################################
' 関数: 排他制御チェック
'#################################################
Private Function IsNoOpen( strZipName )
                   ' エラー無視
                   On Error Resume Next

                   WScript.Sleep 100

                   ' ファイルを追加モードで開いて閉じてみる
                   Call fs.OpenTextFile( strZipName, 8, False ).Close

                   ' エラーが発生しなければ排他がかかっていない
                   IsNoOpen = CBool( (Err.Number = 0) )
End Function



'#################################################
' 関数: 引数チェック
'#################################################
Private Function CreateZip( strZipName, params )
                  Dim objZip, strItem, strName, zipItem, i

                  ' 書庫ファイルが存在していなければ生成
                  If Not fs.FileExists( strZipName ) Then
                      fs.CreateTextFile( strZipName, False ).Write "PK" & Chr(5) & Chr(6) & String(18, 0) ' テキストファイルを生成する
                  End If

                  ' 書庫オブジェクトを取得
                  Set objZip = sh.NameSpace( CStr( strZipName ) )

                  ' For Each strItem In params
                  For i = 1 To params.Count

                       ' 名前の取得
                       strName = fs.GetFileName( params(i )

                       ' 同名のファイルが存在していたら削除
                       Set zipItem = objZip.ParseName( strName ) ' <- ここでエラー
                       If Not (zipItem Is Nothing) Then
                           Call zipItem.InvokeVerb( "削除(&D)" )
                       End If

                       ' 書庫への追加
                       zipobj.CopyHere strItem

                       ' 書庫が排他状態で開けるまで処理続行
                       Do Until IsNoOpen( strZipName )
                       Loop
                  Next

                  CreateZip = True
End Function

ダイアログは極力 出したくないので、元プログラムには "上書きするかどうか..."みたいなダイアログが出る場合の処理等を省いています。

すると、なぜか コメントの "<- ここでエラー" の行でエラーが出ます。

「objZipが無い」みたいなエラー。

それより前の行で

Set objZip = sh.NameSpace( CStr( strZipName ) )

とやっているし、変数宣言も行っています。

変数名を変更しても同じようなエラー。( もちろんその場合は変数名も違いますが。 )

VBSは不慣れなのでイメージができません...

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

コマンドラインから実行した場合、WSH.Argumentsにはカレントディレクトリからの相対パスが入っていると思います。

Scripting.FileSystemObjectの場合、GetAbsolutePathNameというメソッドがあるように、カレントディレクトリを認識して、絶対パスとなるよう補完して動作しているようです。

しかし、動作を見る限りShell.Applicationはカレントディレクトリを認識せず、NameSpaceメソッドは失敗してもエラーを出さないようです。

この動作を見る限り、引数のパスは一旦絶対パスに変換してから処理した方が無難そうですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る