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

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

新規登録して質問してみよう
ただいま回答率
85.48%
VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

Q&A

解決済

5回答

12365閲覧

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

kuroro1991

総合スコア23

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

0グッド

0クリップ

投稿2019/01/24 13:57

前提・実現したいこと

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

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

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

error

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

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

該当のソースコード

vbs

1'Option Explicit 2'On Error Resume Next 3 4Dim strFileName 'ファイルパスを格納 5Dim objApp 'オブジェクトを生成 6Dim objFileSys 'オブジェクトを生成(ファイルシステム) 7Dim strExtension '拡張子を格納 8Dim temp 9 10 11For i=0 to Wscript.Arguments.Count-1 12 'ファイルパスを取得 13 strFileName = Wscript.Arguments(i) 14 temp = Mid(Wscript.Arguments(i), InStrRev(Wscript.Arguments(i), "\") + 1) 15 16 'ファイルシステムを扱うオブジェクトを生成 17 Set objFileSys = CreateObject("Scripting.FileSystemObject") 18 19 '拡張子を取得 20 strExtension = objFileSys.GetExtensionName(strFileName) 21 '拡張子を表示 22 'Wscript.Echo strExtension 23 Wscript.Echo "filename:" & temp 24 Wscript.Echo "Len:" & Len(strFileName) 25 26 'ファイルの存在確認 27 If objFileSys.FileExists(strFileName) Then 28 Wscript.Echo "File OK" 29 End If 30 31 32 If (strExtension = "xls") OR (strExtension = "xlsx") OR (strExtension = "xlsm") OR _ 33 (strExtension = "XLS") OR (strExtension = "XLSX") OR (strExtension = "XLSM") then 34 'Excel関連処理 35 '起動 36 Set objApp = Wscript.CreateObject("Excel.Application") 37 '画面表示 38 objApp.Visible = True 39 '読み取り専用で開く(Excel) 40 Call objApp.Workbooks.Open(strFileName,,True) 41 42 Else 43 Wscript.Echo "拡張子 " & strExtension & " は対象外のファイルです" 44 End If 45 46 '終了処理 47 Set objWshNetwork = Nothing 48 Set objApp = Nothing 49Next 50 51Wscript.Quit 52

試したこと

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttyp03

2019/01/25 00:05

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

2019/01/27 03:01

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

回答5

0

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

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

cmd

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

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

vbs

1' Option Explicit 2' エラー発生時にも処理を続行するよう設定 3' On Error Resume Next 4 5Dim objFileSys 'オブジェクトを生成(ファイルシステム) 6Dim strFolder ' コピー先フォルダ名 7 8Set objFileSys = WScript.CreateObject("Scripting.FileSystemObject") 9strFolder = Wscript.Arguments(0) 10 11For i=1 to Wscript.Arguments.Count-1 12 'ファイルパスを取得 13 strFileName = Wscript.Arguments(i) 14 'WScript.Echo strFileName 15 'ファイルを上書きコピー 16 Call objFileSys.CopyFile(strFileName, strFolder) 17 18Next 19 20Set objFileSys = Nothing

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

bat

1REM @echo off 2echo off 3rem ローカルフォルダの作成場所 4set local_folder="C:\Copy\" 5rem ツールのパス 6set tool_path="C:\Users*****\script\local_copy.vbs" 7 8echo ***** ローカルコピーツール ***** 9echo 10 11rem 作業用フォルダの存在チェック 12IF NOT EXIST "%local_folder%" ( 13 rem フォルダが存在しない場合:フォルダ作成 14 mkdir %local_folder% 15 echo フォルダは存在していません 16) Else ( 17 echo フォルダはすでに存在しています 18) 19 20:start 21IF "%~1" == "" GOTO finish 22 23echo %tool_path% %local_folder% %~1 24%tool_path% %local_folder% %~1 25 26:next 27SHIFT 28GOTO start 29 30:finish 31pause 32rem EXIT

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


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

投稿2019/01/27 02:40

kuroro1991

総合スコア23

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuroro1991

2019/01/27 02:46 編集

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

0

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

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

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

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

投稿2019/01/26 08:38

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuroro1991

2019/01/27 02:51

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

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 08:56

編集2019/01/25 08:59
jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jawa

2019/01/25 09:02

入れ違いでlazybones2000さんへのコメントを見ました。 いくつかの案は没っぽいですね。。 複数の端末へ適用したいということは、使う人も複数ということでしょうか。 ・・・となると「ファイルを開いてから読み取り専用を解除する」という策も絶対忘れる人が出ますし、何より設定が面倒ですね。。
kuroro1991

2019/01/27 02:51

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

0

ベストアンサー

試してみました。

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

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

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

投稿2019/01/25 00:21

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuroro1991

2019/01/25 04:51 編集

回答ありがとうございます。 WScript.Argumentsに値は正しく格納されますでしょうか? 自分の環境では長いパス名を引数として渡すとどうしてもパス名が途中で切れてしまっている出力されるのですが・・・ vbsファイルの中でパスを指定してもOpenでエラーになるということは私も確認できたので引数が正しく渡されたとしても解決にはつながらないということは認識しました。 解決案ですが 1.対象としたいフォルダが数多くあるためmklinkで対策するのは難しいと思われます 2.ローカルにコピーすれば開けるようになることはわかるのですが、ファイルをほんの少し閲覧するためにローカル環境にコピーするのは面倒に感じています。また、コピー元ファイルの更新頻度が高いとコピーする作業もその都度行う必要があるため、コピーではなく右クリック⇒送るの機能をつかって解決できないかを模索していました。
ttyp03

2019/01/25 04:53

これくらいのパス(作成できる限界)は無事に受け取れています。 C:\Temp\chon\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\012345678901234567890123456789\test.xlsx 複数個渡しても大丈夫でしたよ。 コピーする案は、手動でやるのではなく、スクリプト内で自動でコピーしたらどうですか?ということです。
kuroro1991

2019/01/25 05:25

提示していただいたパスでは確かにファイル名まで正しく表示されていました。 私の環境はもう少し長いパス名のようです。 私が試した環境は以下の通りです。 【読み取り専用で開きたいファイル(引数として渡すもの)】 --------------------------------------------------------------------------------------------------------- C:\Users\abcdse\TempData\Programming\script\読み取り専用\テストデータ\359aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\258_a.docx --------------------------------------------------------------------------------------------------------- 【実行結果(WScript.Argumentsのデータ)】 C:\Users\abcdse\TempData\Programming\script\読み取り専用\テストデータ\359aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\25 --------------------------------------------------------------------------------------------------------- 【切れてしまったデータ】 8_a.docx --------------------------------------------------------------------------------------------------------- コピーする案もパス名が途中で切れてしまっているのが現状なので同様の問題が発生するかと思います。 作成できる限界についてはよくわかりませんが私の環境だとこれらのファイルが作成できています。
ttyp03

2019/01/25 05:37 編集

確かにダメでした。 というかスクリプト自体動きませんでした。 どうやらパス名の最大は文字数っぽいですが、VBSでの受け取りはバイト数のような気がします。 なのでパス名に日本語を含んでいるとバイト数が受け取れる上限を超えてしまうので、フォルダ名に日本語を使わないようにすればよいと思います。 それができない環境ですと、パス名自体受け取ることができないのでどうしようもないですね。。。
退会済みユーザー

退会済みユーザー

2019/01/25 05:54 編集

このポリシーについては、ちょうど試していたんですが、コマンドプロンプトなどでは長いパスを扱えるようになったにもかかわらず、それでもなおExcel(2013x86)では長いパスのファイルは開けなかったので、Excelではファイルが見つからないとなって開けないんですよね。 Excelのバージョンとかが違えば行けるんですかね。
ttyp03

2019/01/25 06:02

lazybones2000さん> 確かにExcelで引っかかる可能性はありますね。 Windows10の環境が今ないので確認はできないのですが、VBSでは正しく受け取れるのでしょうか? ここで引っかかる可能性もありますよね。 無事受け取れるなら、私の回答している「コピーしてから開く」の方法にすれば解決できるかと。
退会済みユーザー

退会済みユーザー

2019/01/25 07: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 実行時エラー: パスが見つかりません。 ---
kuroro1991

2019/01/27 02:42 編集

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

0

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

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

bat

1mklink /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/24 15:36

編集2019/01/24 15:41
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuroro1991

2019/01/25 04:31

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

退会済みユーザー

2019/01/25 05:59

読み取り専用で開くメニューのことはご存じだったのですね。失礼しました。 ttyp03さんのファイルコピー案を何とか実現するしかないかもしれないですね。 もし、ドメイン環境でドメインのポリシー設定も可能なのであれば、レジストリー設定は各端末で設定作業をしなくとも設定変更は可能です。こちらもご存じであれば流してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問