VBで新規にエクセルファイルを作成し、名前を付けて保存したいと考えてます。
内容が良く分かっていないのですが、いろいろ調べて、2つの方法でできるようにはなりました。下記の1と2です。
1
xlFName = xlApp.GetSaveAsFilename(fileFilter:="Excel (*.xls), *.xls")
Call xlBok.SaveAs(xlFName)
2
Application.Dialogs(xlDialogSaveAs).Show
ところが、どちらの方法でも「名前を付けて保存」のウィンドウが走らせているプログラムの裏に出てしまい、プログラムのウィンドウをあらかじめ端に寄せておかないとアクセスすることができません。
普通のアプリケーションと同じように、「名前〜」のウィンドウを一番手前に出すためには何か特別な操作が必要なんでしょうか?
> VBで新規にエクセルファイルを作成し、名前を付けて保存したいと考えてます。
単純に、
『「Excelのダイアログ」を使わないで、「VBのダイアログコントロール」を使う』
じゃ駄目なんでしょうか?
VBのダイアログコントロールを使ったら、空のファイルが保存され、その後「・・を上書きします」のダイアログが現れてしまい、訳が分からないので諦めました。
すみません。VBは全く初心者で、基本を本で勉強しただけで詳しいことが何も分からずにやってますのでうまく質問に応える事もできなくて・・
確認を忘れてました。
VBのバージョンは何です?
#VB6とか?
> VBのダイアログコントロールを使ったら、空のファイルが保存され、
> その後「・・を上書きします」のダイアログが現れてしまい、
VBのダイアログコントロールにファイルを保存したりする機能は無いはずですけど・・・
#単に、「ファイル名を参照する」だけのはず。
どういうプログラムを書いたんでしょう・・・
ちなみに、私は、
> どちらの方法でも「名前を付けて保存」のウィンドウが走らせているプログラムの裏に出てしまい、
この現象を見たことが無いので、
> 何か特別な操作が必要なんでしょうか?
には、答えられません。
VBはVer6です。
コモンダイアログを使うプログラムは下記です。
CommonDialog1.Filter = "テキストファイル(*.txt)|*.txt|" & "すべてのファイル(*.*)|*.*|"
CommonDialog1.FilterIndex = 1
CommonDialog1.Flags = cdlOFNOverwritePrompt
CommonDialog1.FileName = ""
CommonDialog1.InitDir = App.Path
CommonDialog1.ShowSave
おっしゃるとおり、カレントで操作しているエクセルのファイルと関連付けができません(方法が分かりません)。
今のプログラムは、名前を付けてファイルを保存して終わりたいだけで、下記のように書きました。
Application.Dialogs(xlDialogSaveAs).Show
Call xlApp.Quit
Set xlSht = Nothing
Set xlBok = Nothing
Set xlApp = Nothing
すると、カレントのプログラムだけでなく、全てのウィンドウの一番下に「名前〜」のウィンドウが表示されてしまいます。
コモンダイアログの場合は一番上に出るんですけど・・
続き
ちなみに初期化の部分です
(General)
Dim xlApp As Excel.Application
Dim xlBok As Excel.Workbook
Dim xlSht As Excel.Worksheet
Private Sub Form_Load()
Set xlApp = CreateObject("Excel.Application")
Set xlBok = xlApp.Workbooks.Open("C:\Book1.xls")
Set xlBok = xlApp.Workbooks.Add
Set xlSht = xlBok.Worksheets(1)
xlSht.Activate
End Sub
> カレントで操作しているエクセルのファイルと関連付けができません
SaveAs メソッドを使えば、特定のファイル名で保存させることができます。
> Call xlApp.Quit
ここで処理している「xlApp」とは、VB から CreateObject で
生成した Excel.Application ですよね。
しかし、その直前にある
> Application.Dialogs(xlDialogSaveAs).Show
というのは、xlApp に対する操作にはなっていないため、問題があります。
グローバルオブジェクトである Application を操作してしまうと、
たとえば、CreateObject を 2回行って、同時に 2 つの Excel を
操作するような場合において、どちらの Excel を操作しているのか、
曖昧になりますよね。
このようなコードは、実行時にエラーを誘発してしまったり、
オブジェクトの解放漏れの原因などとなります。
SaveAsで名前を決めてしまわずに「名前を付けて保存」でユーザに名前を付けさせていのです。
理解して使っていないので申し訳ありません。
「Application.Dialogs(xlDialogSaveAs).Show」
の代わりに
xlFName = xlApp.GetSaveAsFilename(fileFilter:="Excel (*.xls), *.xls")
Call xlBok.SaveAs(xlFName)
でも同じになります。
分かりにくくて申し訳有りません。まとめて書くと下記のようになります
Option Explicit
Dim xlApp As Excel.Application
Dim xlBok As Excel.Workbook
Dim xlSht As Excel.Worksheet
Private Sub Form_Load()
Set xlApp = CreateObject("Excel.Application")
Set xlBok = xlApp.Workbooks.Add
Set xlSht = xlBok.Worksheets(1)
xlSht.Activate
End Sub
Private Sub EndBtn_Click()
Dim xlFName As String
On Error Resume Next
xlFName = xlApp.GetSaveAsFilename(fileFilter:="Excel (*.xls), *.xls")
Call xlBok.SaveAs(xlFName)
Call xlApp.Quit
Set xlSht = Nothing
Set xlBok = Nothing
Set xlApp = Nothing
End
End Sub
> SaveAsで名前を決めてしまわずに「名前を付けて保存」でユーザに名前を付けさせていのです。
ん?
ユーザにファイル名を決めさせる部分というのは、
>> CommonDialog1.ShowSave
であって、そこで得られた FileName を使って保存する部分が
>> SaveAs
という代替案ですよね。UI こそ違えど、提示された
「名前を付けて保存」の条件は満たしていそうですが…。
> xlFName = xlApp.GetSaveAsFilename(fileFilter:="Excel (*.xls), *.xls")
これを使うのあれば、事前に、アクティブなアプリケーションを
(VB から)Excel 側へと切り替えておいた方が良いかと思います。
Call xlBok.SaveAs(CommonDialog1.ShowSave)
とすると言うことでしょうか?
>アクティブなアプリケーションを(VB から)Excel 側へと切り替えて
この場合。アクティブなアプリとは、VBで作成したプログラムですよね?
それはどうやったらできるのでしょうか?
> この現象を見たことが無いので、
確かに再現しますね・・・
で、魔界の仮面弁士さんの言われているように、
Excelをアクティブに切り替えなければ駄目でしょうけど・・・
Excelを非表示状態で動作せているので、無理な気が・・・
> Call xlBok.SaveAs(CommonDialog1.ShowSave)
違いますよ。
> >> CommonDialog1.ShowSave
> であって、そこで得られた FileName を使って保存する部分が
ヘルプで、コモンダイアログの「FileName プロパティ」を確認してください。
まさか・・・マルチポスト?
http://okwave.jp/qa3343630.html
↑ 失礼。
友人に質問したところ、彼もわからなかったようで、ここに書いたようです。
デバッグ中のプログラムを上書き保存した後、テスト用のプログラムに修正し、名前を付けてプロジェクトを保存したのに、元のデバッグ中のプログラムまで修正されてしまいました。
ちょっと元に戻すのに時間がかかると思いますので、しばらくアクセスできないかもしれませんが悪しからず・・
ソースの復旧は完了しましたが、相変わらず状況は変わりません。
「名前を〜」のウィンドウを出す前に、エクセルを表示させないといけないのでしょうか?
>魔界の仮面弁士さま
>> xlFName = xlApp.GetSaveAsFilename(fileFilter:="Excel (*.xls), *.xls")
>これを使うのあれば、事前に、アクティブなアプリケーションを
>(VB から)Excel 側へと切り替えておいた方が良いかと思います。
あまりに初心者でおっしゃる意味が理解できないでいました。
今、ようやく理解できました。
もしかして先に
xlApp.Visible = True
を入れておくと言うことでしょうか?
このときエクセルが表示されてわずらわしいのですが、これで一応解決しました。
ありがとうございました。
もっとスマートな解決方法があるかもしれませんが、今の私には難しいようです。
あ。
解決チェック入っちゃいましたが、見てくれることを願って。
Visible = False のときに、Excel 所属のウィンドウを表示させるとこのような現象がおきます。
VBAでも同様です。
このようなときは、Visible = True とすればいいです。
ただし、Excel を最小化して。
xlApp.WindowState = xlMinimized
xlApp.Visible = True
xlFName = xlApp.GetSaveAsFilename(fileFilter:="Excel (*.xls), *.xls")
Call xlBok.SaveAs(xlFName)
Call xlApp.Quit
とすれば、シートが表示されることも無く、期待通りの動作をするはずです。
紅閃光様
ありがとうございました。
おかげさまで思ったとおりの動作をするようになりました。
ツイート | ![]() |