C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

xlsmファイルをxlsxファイルに変換したい

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■92540 / inTopicNo.1)  xlsmファイルをxlsxファイルに変換したい
  
□投稿者/ 佐藤 (1回)-(2019/10/03(Thu) 13:01:44)

分類:[.NET 全般] 

表題の件、とあるファイルに入っているxlsmファイルを、全てxlsxファイルに変換したいです。
76エラーが出ます。
マクロなしブックにしますか?という問いも出てきてしまいます。

また、力不足ですが、保存するファイル先も選びたいのですが、どう組めばよいのかわからず同じファイルに出力しています。


Option Explicit
Dim bk, ex, f, gf, so
Set so = CreateObject("Scripting.FileSystemObject")
Set gf = so.GetFolder(so.GetParentFolderName(WScript.ScriptFullName))
Set ex = CreateObject("Excel.Application")
ex.Application.DisplayAlerts = False
ex.Visible = False
For Each f In gf.Files
If LCase(so.GetExtensionName(f.Name)) = "xlsm"Then
Set bk = ex.Workbooks.Open(gf &"\"&f.Name)
bk.SaveAs gf &"\"&so.GetBaseName(f.Name) &".xlsx", 51
bk.Close
Set bk = Nothing
End If
Next
ex.Quit
Set ex = Nothing
Set gf = Nothing
Set so = Nothing
MsgBox("Finished!")

引用返信 編集キー/
■92541 / inTopicNo.2)  Re[1]: xlsmファイルをxlsxファイルに変換したい
□投稿者/ 魔界の仮面弁士 (2407回)-(2019/10/03(Thu) 14:08:18)
No92540 (佐藤 さん) に返信
> 表題の件、

質問内容を見る限りでは、分類は [.NET 全般] ではなく、[VBScript] なのでは?
とりあえず VBScript 前提で回答します。


> とあるファイルに入っているxlsmファイルを、
ファイルにファイルが入っている…?

「とあるフォルダに入っている .xlsm ファイル」の間違いでしょうか。
あるいは、「.zip ファイル内に入っている .xlsm ファイル」のような意味?

とりあえず『とある .xlsm ファイル』と読み替えて回答します。


> 全てxlsxファイルに変換したいです。
.xlsm は「Excel マクロ有効ブック」
.xlsx は「Excel ブック」と呼ばれますが、
後者には VBA コードや Excel 4.0 マクロシートを含めることができません。

.xlsb であれば含められます。


> 76エラーが出ます。

実行時エラー 76 は、「パスが見つかりません。」の意味ですね。
どの行で発生しているかは確認済みでしょうか?
指定したフルパスが間違っていないか、再確認してみてください。


また、ファイルアクセスである以上、76 以外のエラーとなる可能性もあります。

たとえば Excel で "Book1.xlsm" を開く場合、同じ場所に
隠しファイル "~$Book1.xlsm" が同時に生成されることになりますが、
列挙タイミングによっては、これも For Each で拾われてしまう可能性があり、
これを Excel 本体で開こうとすると、不正形式エラー(1004 など)となりえます。
そのほか、
 ・アクセス権が無い
 ・該当ファイルが別のプログラム(Excelとか)で開かれていた
 ・セキュリティソフトによる監査で FileSystemObject の処理が阻害された
などの可能性もあります。On Error Resume Next を併用して判定しましょう。



> ex.Application.DisplayAlerts = False
これは
 ex.DisplayAlerts = False
だけで構いません。
Application プロパティは Application オブジェクトを返すので、
 ex.Application.Application.Application.Application.Application.DisplayAlerts = False
などとも書けますが、明らかに冗長ですよね。

> ex.Visible = False
プログラムが完成するまでは True にしておいた方が確認しやすいですよ。


> Set bk = ex.Workbooks.Open(gf & "\" & f.Name)
上記は
 Set bk = ex.Workbooks.Open(so.BuildPath(gf.Path, f.Name))
とすべきです。


スクリプトの配置先によっては、gf がルートフォルダとなる可能性が
あるわけですが、もしも gf が "D:\" フォルダーを参照していた場合、
前者は "D:\\Book1.xlsm"
後者は "D:\Book1.xlsm"
というパスになるという違いがあります。
\\ と連ねても動いてしまうケースもありますが、正しい指定では無いですね。


> bk.SaveAs gf &"\"&so.GetBaseName(f.Name) &".xlsx", 51
こちらのパス指定も、
 bk.SaveAs so.BuildPath(gf.Path, so.GetBaseName(f.Name) & ".xlsx"), 51
が良いでしょう。
最後の引数の 51 は .xlsx 指定の意味ですね。

 Const xlExcel12 = 50 '.xlsb(Excel バイナリブック)
 Const xlOpenXMLWorkbook = 51 '.xlsx(Excel ブック)
 Const xlOpenXMLWorkbookMacroEnabled = 52 '.xlsm(Excel マクロ有効ブック)
 Const xlOpenXMLTemplateMacroEnabled = 53 '.xlsm(Excel マクロ有効テンプレート)
 Const xlOpenXMLTemplate = 54 '.xltx(Excel テンプレート)
引用返信 編集キー/
■92542 / inTopicNo.3)  Re[2]: xlsmファイルをxlsxファイルに変換したい
□投稿者/ 魔界の仮面弁士 (2408回)-(2019/10/03(Thu) 16:11:56)
No92541 (魔界の仮面弁士) に追記
>>Set bk = ex.Workbooks.Open(gf & "\" & f.Name)
> 上記は
>  Set bk = ex.Workbooks.Open(so.BuildPath(gf.Path, f.Name))
> とすべきです。

失礼しました。
SaveAs の時は、保存先のパスを構築する必要がありますが、
Open 時はその必要が無いので、もっと単純に
 Set bk = ex.Workbooks.Open(f.Path)
だけで OK ですね。



No92540 (佐藤 さん) に返信
> 保存するファイル先も選びたいのですが、どう組めばよいのかわからず同じファイルに出力しています。

どのように指定させることを想定しておられますか?
それによって組み方も変わって来ます。


「保存するファイル先」といっても、ループ中、ファイルごとに
毎回 InputBox 関数などで問い合わせるというのも面倒ですし、
特定のフォルダーに一括出力してしまうのが良いかもしれませんね。

たとえば、特定の固定パス(ドキュメント フォルダーなど)に
上書き出力させるという設計にもできるでしょう。

あるいは現在のフォルダーに年月日日時分秒のサブフォルダー
(例えば "2019-10-03_13;01;44" など)を CreateFolder で作成し、
そのフォルダー内に SaveAs させていくという方法もあろうかと思います。


> マクロなしブックにしますか?という問いも出てきてしまいます。
DisplayAlerts = False が効いていれば、問い合わせは行われないと思います。

それでも表示されるという事は、いずれかの .xlsm に Sub Workbook_Open() が仕込まれていて、
そこで自動起動された処理が悪影響を及ぼしているのかもしれません。
念のため、ループ中に毎回 EnableEvents を False にしておいては如何でしょうか。

For Each f In gf.Files
 If LCase(so.GetExtensionName(f.Name)) = "xlsm"Then
  OldEnableEventsValue = ex.EnableEvents
  ex.EnableEvents = False
  Set bk = ex.Workbooks.Open(f.Path)
  bk.SaveAs 〜〜〜
  ex.EnableEvents = OldEnableEventsValue
  bk.Close
  Set bk = Nothing
 End If
Next

Workbooks.Oe


引用返信 編集キー/
■92543 / inTopicNo.4)  Re[3]: xlsmファイルをxlsxファイルに変換したい
□投稿者/ 佐藤 (2回)-(2019/10/03(Thu) 17:31:11)
>>どのように指定させることを想定しておられますか?
>>それによって組み方も変わって来ます。

出力フォルダを作成して、そこに出力しようかと考えております。
慌てて質問してしまい、不備がありすみません。

他は問題なく処理が出来ました!
引用返信 編集キー/
■92544 / inTopicNo.5)  Re[4]: xlsmファイルをxlsxファイルに変換したい
□投稿者/ 魔界の仮面弁士 (2409回)-(2019/10/03(Thu) 18:16:28)
No92543 (佐藤 さん) に返信
> 他は問題なく処理が出来ました!

原因は何だったのでしょうか?
細かい差異はあるものの、コードそのものに大きな問題は無かったように思えたのですが。


> 出力フォルダを作成して、そこに出力しようかと考えております。

たとえば現在時刻のサブフォルダーを作って、そこに SaveAs するとか。

Dim dt, ymd, hns, subDirName, subDirPath
dt = Now()
ymd = Year(dt) * 10000 + Month(dt) * 100 + Day(dt)
hns = Hour(dt) * 10000 + Minute(dt) * 100 + Second(dt)
subDirName = CStr(ymd * CCur(1000000) + hns)
subDirPath = so.BuildPath(gf.Path, subDirName)

MsgBox subDirPath, vbSystemModal

so.CreateFolder subDirPath


フォルダーを作成しようとしたら、たまたま同名のファイルが存在していたとか、
そもそもアクセス権が無かったなんてパターンもあるので、
実際には On Error 処理も必要です。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ