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

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

ただいまの
回答率

89.10%

Excelファイルを読み取り専用で開くVBSを作成したい

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 3,071

kuroro1991

score 21

前提・実現したいこと

Excelファイルを読み取り専用で開くためのvbsを作成しています。
下記vbsファイルをshell:sendToに格納し開きたいファイルを右クリック⇒送るで動作させることで
対象のExcelファイルを読み取り専用で開くものですがファイルパスが長すぎると正常に動作せず困っています。
どのようにすれば解決できるでしょうか。

発生している問題・エラーメッセージ

ファイルパスが長くなければ正常に動作することを確認できたのですが、
ファイルのフルパスが255文字を超えるような長いパス名を持ったファイルについては正常に動作しません。
エラーメッセージは特に出力されませんが、Excelファイルを開こうとしても

拡張子は対象外のファイルです


と出力され意図しない動作となります。
長いパスだとvbsファイルに引数として渡している Wscript.Arguments がパスの途中で切れてしまっており、
正常に格納できていないことが原因のようです。

該当のソースコード

'Option Explicit
'On Error Resume Next

Dim strFileName     'ファイルパスを格納
Dim objApp          'オブジェクトを生成
Dim objFileSys      'オブジェクトを生成(ファイルシステム)
Dim strExtension    '拡張子を格納
Dim temp


For i=0 to Wscript.Arguments.Count-1
    'ファイルパスを取得
    strFileName = Wscript.Arguments(i)
    temp = Mid(Wscript.Arguments(i), InStrRev(Wscript.Arguments(i), "\") + 1)

    'ファイルシステムを扱うオブジェクトを生成
    Set objFileSys = CreateObject("Scripting.FileSystemObject")

    '拡張子を取得
    strExtension = objFileSys.GetExtensionName(strFileName)
    '拡張子を表示
    'Wscript.Echo strExtension
    Wscript.Echo "filename:" &  temp
    Wscript.Echo "Len:" &  Len(strFileName)

    'ファイルの存在確認
    If objFileSys.FileExists(strFileName) Then
        Wscript.Echo "File OK"
    End If


    If (strExtension = "xls") OR (strExtension = "xlsx") OR (strExtension = "xlsm") OR _
       (strExtension = "XLS") OR (strExtension = "XLSX") OR (strExtension = "XLSM") then
       'Excel関連処理
       '起動
       Set objApp = Wscript.CreateObject("Excel.Application")
       '画面表示
       objApp.Visible = True
       '読み取り専用で開く(Excel)
       Call objApp.Workbooks.Open(strFileName,,True)

    Else
        Wscript.Echo "拡張子 " & strExtension & " は対象外のファイルです"
    End If

    '終了処理
    Set objWshNetwork = Nothing
    Set objApp = Nothing
Next

Wscript.Quit

試したこと

ショートパス⇔ロングパスの変換を試してみましたがファイルパスが途中で切れてしまっているためか正常に動作しませんでした。

補足情報(FW/ツールのバージョンなど)

動作環境
OS:Windows 10 Pro(64bit)

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • ttyp03

    2019/01/25 09:05

    質問内容に適したタイトルにしてください。読み取り専用で開けない問題ではなく、ファイルパスが長いと引数が正しく受け取れないという問題ですよね。

    キャンセル

  • kuroro1991

    2019/01/27 12:01

    すいません修正し忘れました。今後気をつけます。

    キャンセル

回答 5

checkベストアンサー

0

試してみました。

  • WScript.Argumentsには正しく格納されている。
  • Openでエラーになる。
  • Excelファイルをエクスプローラーから直接開いても同じエラーになる。

解決案

  1. 他の回答にあるようにリンクを使う
  2. 対象のファイルを一旦別のフォルダにコピーしそれを使う

そもそも読み取り専用で開きたいとのことなので、コピーしたのを使うことで問題ないと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/25 15:02

    lazybones2000さん>
    確かにExcelで引っかかる可能性はありますね。
    Windows10の環境が今ないので確認はできないのですが、VBSでは正しく受け取れるのでしょうか?
    ここで引っかかる可能性もありますよね。

    無事受け取れるなら、私の回答している「コピーしてから開く」の方法にすれば解決できるかと。

    キャンセル

  • 2019/01/25 16:37

    先ほどはコピペ編集で変な文を貼ってしまいすみません。
    引数はかなり長くても受け取れますが、コピーはfso.copyfile以外の方法が必要ですね。copyコマンドではコピーできるので、shell.run "cmd.exe /c copy (略"って感じでしょうか。
    ---スクリプト
    set fso = CreateObject("Scripting.FileSystemObject")
    for each arg in Wscript.Arguments
    wscript.echo "[" + arg + "]"
    fso.copyfile arg, "c:\temp\"
    next
    ---実行コマンド
    C:\Users\lazybones2000\Documents>cscript /nologo argtest.vbs argtest.vbs "c:\Users\lazybones2000\Documents\ほげほげほげ\ほげほげほげ\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\新規 Microsoft Excel ワークシート.xlsx"
    ---結果
    [argtest.vbs]
    [c:\Users\lazybones2000\Documents\ほげほげほげ\ほげほげほげ\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\新規 Microsoft Excel ワークシート.xlsx]
    C:\Users\lazybones2000\Documents\argtest.vbs(4, 1) Microsoft VBScript 実行時エラー: パスが見つかりません。
    ---

    キャンセル

  • 2019/01/27 11:18 編集

    パス名が途中で切れてしまっている問題を解決できたのでローカルフォルダにコピーする案を採用させていただくことで解決を図ることができました。
    回答ありがとうございました。

    参考までに「解決方法」の欄にソースコード記載させていただきます。

    キャンセル

0

長いパス名のファイルを開けないことの根本的な回避策はないと思っています。

対象としたいフォルダーが決まっているならば、浅いパスにmklinkコマンドの/dか/jでそのフォルダーへのリンクを作成しておき、そこからアクセスするとかでしょうか。下記コマンドを一度実行しておけば、以降は<なんかすごく長いパス>フォルダー下のファイルには、<短いパス>フォルダー下にあるかのようにアクセスできます。
なお、管理者として実行されたコマンドプロンプトなどで実行が必要です。

mklink /d <短いパス> <なんかすごく長いパス>

ところで、長いパス名対策にはなりませんが、エクスプローラーから開く際のツールとして今回のVBSを作ろうとしているならば、エクスプローラー上でファイルをShiftキーを押しながら右クリックすれば、読み取り専用で開くのメニューが出ますので、そちらを使われるのはどうでしょうか。
ただしこの設定にバグがあり、そのままだと読み取り専用で開いてくれないため、レジストリ値の設定が必要です。
\HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\OpenAsReadOnly\ddeexec(規定)のデータを[open("%1",,,,,,,,,,,,,,1,,1)]から[open("%1",,1)]に変更します。キーはExcel2010の例ですが、違うバージョンでしたら.12の部分を適宜変更してみてください。対象としたい拡張子によっては、近くの似たようなレジストリも同様に設定する必要があるかもしれません。

この設定バグ、かなり昔からあるのですが、MSは直す気が無いんでしょうね…。
さらに、なんらかのトリガーで(WindowsUpdateあたりでしょう)で値が戻ってしまうことがある気がしています。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/25 13:31

    複数の回避策を提示していただきましてありがとうございます。
    1.対象としたいフォルダは数えきれないほどあるため、mklinkでも解決できそうにないです。
    2.質問内容に書いていませんでしたが複数のPCで使いたいプログラムのためレジストリ値の変更で解決することは知っていたのですが、PCごとに設定しなければならないためvbsで解決したいと考えていました。

    もう少し何とかできないか模索したいと思います。
    対応ありがとうございました。

    キャンセル

  • 2019/01/25 14:59

    読み取り専用で開くメニューのことはご存じだったのですね。失礼しました。
    ttyp03さんのファイルコピー案を何とか実現するしかないかもしれないですね。

    もし、ドメイン環境でドメインのポリシー設定も可能なのであれば、レジストリー設定は各端末で設定作業をしなくとも設定変更は可能です。こちらもご存じであれば流してください。

    キャンセル

0

たしかWindowsの制限でファイル名(パス含む)は最大255文字、Excel側の制限でファイル名(パス含む)は218文字、といった制限があったと思うのですが…

自分の環境(Win7/Office2010)で確認してみたところ、ものすごく長いはフォルダにxlsxファイルを置こうとするとその時点でOSに怒られたり、少し短くしてファイルを置けてもファイルをダブルクリックで開くとExcelがエラーメッセージを表示して開けなかったりしました。
これだけなら想定通りなのですが、その長いフォルダごと別のフォルダ内においてみると全体260文字超えなのにファイルを置くときに怒られなかったり、Excelでも開けてしまったり、何ともはっきりしたことが言えなくなってしまいました。
どちらも全て半角のパスなのですが。汗

まずはvbsからではなく、普通にExcelで開けるかの確認をしておきたいところですね。


普通にExcelで開けないのなら、
・別フォルダにコピーしたものを開く(ttyp03さん案)
くらいしか回避策が思い当りません。

リンクを作成する方法は、長いパス(の途中まででも)が変わらないのなら有効だと思います。
長いパスもその時々で変わるのなら、その都度リンクを作らなければならないですね。(その処理もVBSに含めるとか?)


もしExcelで普通に開けるのなら、
・「読み取り専用で開く」を使う(lazybones2000さん案)
・開いてから読み取り専用に切り替える(Excelのリボン設定で「読み取り専用の設定/解除」を追加)
といったコーディング以外の部分での回避策は有効だと思います。

ダブルクリックなどで開けるのですから、もしかしたらコーディングで
・ブックのあるフォルダをカレントフォルダにしてOpenする
といった方法でも回避できるのかもしれません。
これについてはパっと思いつく限り(VBSの作業フォルダを変更する/Excelオブジェクトのデフォルトパスプロパティを変更する)を手元の環境で試してみましたが、Openでのエラーが回避できませんでした。
方向性としてはアリなような気がするのですが・・・。


まずは普通に開けるかの確認からお願いしたいです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/25 18:02

    入れ違いでlazybones2000さんへのコメントを見ました。
    いくつかの案は没っぽいですね。。

    複数の端末へ適用したいということは、使う人も複数ということでしょうか。
    ・・・となると「ファイルを開いてから読み取り専用を解除する」という策も絶対忘れる人が出ますし、何より設定が面倒ですね。。

    キャンセル

  • 2019/01/27 11:51

    コメントありがとうございます。参考にさせていただきました。

    キャンセル

0

コメントにしようか迷ったのですが、違うアプローチなので回答にて。

あまりおすすめできる方法ではないですが、どうしてもという場合は、8.3形式(Program FilesProgra~1とする)で使うのはどうでしょうか。ファイル名やフォルダー名が長いためにフルパス名が長くなっているならば、有効な回避策ではあります。

とはいえ、今更使うような仕様ではないと思っていますし、この形式のデータを保持していないようにしている環境も少なくはないと思いますのでご参考程度に。

PS そういえば昔のWindowsの高速化TIPSとして、この形式を無効にするってありましたね。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/27 11:51

    回答ありがとうございます。おかげさまで何とか解決するとことができました。

    キャンセル

0

パス名が途中で切れてしまう問題について

「右クリック送る」では遅れませんでしたが以下のようにコマンドプロンプトから直接指定すればロングパスも引数として渡せるようです。

wscript.exe 【本スクリプトファイル.vbs】 【引数(右クリック送るで指定したファイル)】

ただ引数が渡されてもExcelファイルがOpenでエラーとなってしまうためローカルにコピーする案を採用させていただきました。
以下ソースコードになります。

' Option Explicit
' エラー発生時にも処理を続行するよう設定
' On Error Resume Next

Dim objFileSys  'オブジェクトを生成(ファイルシステム)
Dim strFolder   ' コピー先フォルダ名

Set objFileSys = WScript.CreateObject("Scripting.FileSystemObject")
strFolder = Wscript.Arguments(0) 

For i=1 to Wscript.Arguments.Count-1
    'ファイルパスを取得
    strFileName = Wscript.Arguments(i)
    'WScript.Echo strFileName
    'ファイルを上書きコピー
    Call objFileSys.CopyFile(strFileName, strFolder)

Next

Set objFileSys = Nothing

vbsファイルを呼び出すbatファイル。このファイルをsendtoに登録しておく

REM @echo off
echo off
rem ローカルフォルダの作成場所
set local_folder="C:\Copy\"
rem ツールのパス
set tool_path="C:\Users\*****\script\local_copy.vbs"

echo ***** ローカルコピーツール *****
echo

rem 作業用フォルダの存在チェック
IF NOT EXIST "%local_folder%" (
    rem フォルダが存在しない場合:フォルダ作成
    mkdir %local_folder%
    echo フォルダは存在していません
) Else (
    echo フォルダはすでに存在しています
)

:start
IF "%~1" == "" GOTO finish

echo %tool_path% %local_folder% %~1 
%tool_path% %local_folder% %~1 

:next
SHIFT
GOTO start

:finish
pause
rem EXIT

使い方
コピーしたいファイルを選択⇒右クリック送る⇒batファイルを選択


参考URL:http://d.hatena.ne.jp/satob/touch/20120223

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/27 11:45 編集

    読み取り専用で開きたい場合についてですが、まだ試してはいないのですがロングパス⇔ショートパスの変換機能をvbsに入れておけばOpenエラ-を回避できるかもしれません。

    キャンセル

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

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