Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1516 / 2272 ツリー ←次へ | 前へ→

【6745】エクセル出力 Mino 05/11/5(土) 15:13 質問[未読]
【6747】Re:エクセル出力 小僧 05/11/5(土) 18:00 発言[未読]
【6749】Re:エクセル出力 YU-TANG 05/11/5(土) 21:31 回答[未読]
【6751】【解決】Re:エクセル出力 Mino 05/11/6(日) 11:41 お礼[未読]
【6753】Re:【解決】Re:エクセル出力 小僧 05/11/6(日) 19:53 回答[未読]
【6754】Re:【解決】Re:エクセル出力 小僧 05/11/6(日) 20:05 回答[未読]
【6755】Re:【解決】Re:エクセル出力 小僧 05/11/6(日) 22:19 発言[未読]
【6770】Re:【解決】Re:エクセル出力 Mino 05/11/8(火) 18:57 お礼[未読]
【6771】Re:【解決】Re:エクセル出力 YU-TANG 05/11/8(火) 19:13 発言[未読]
【6786】Re:【解決】Re:エクセル出力 Mino 05/11/10(木) 9:21 発言[未読]
【6789】Re:【解決】Re:エクセル出力 YU-TANG 05/11/10(木) 12:47 回答[未読]

【6745】エクセル出力
質問  Mino  - 05/11/5(土) 15:13 -

引用なし
パスワード
   初心者です。

今、あるフォームにエクセル、CSV出力ボタンを設け、
画面のデータをエクセルへ出力するようにしています。

エクセルへ出力する内容は、
クエリーで抽出した内容そのままです。

保存先を指定する「ダイアログ」を表示させて、
ファイル名を入力し、保存ボタンを押して、保存します。
又、既存のファイルに対しても、
「上書きしますか?」とメッセージが表示され、
上書き保存が可能です。
ここまでは正常に内容を出力できました。

問題は「既存のファイル」に対して、
上書きを行う時に、
そのファイルが開いている(オープン中の)場合です。
その場合、エラーが発生してしまいます。

エラー箇所は、
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, 「クエリー名」, 「保管先+ファイル名」, True
で、
エラー番号:3010
エラー内容:テーブル「クエリー名」は既に存在しています。
です。

何か、良い回避方法がありますか?
  On Error GoTo
で、強制的に?回避をしようやってみましたが、
開いているエクセルに対して、更新がかかったのか、
内容がクリアされてしまいます。
更には、次にエクセルを起動しようとすれば、起動できなくなっています。
(タスクマネージャーからEXCELを終了させれば、起動出来ましたが・・・)

又、既に開いているファイルを検索して、
(上書きの)指定したファイルと同じファイル名が存在していれば、
処理を行わないようなロジックを組みましたが、
上手くいきませんでした。

どんな方法でも結構ですので、
どなたか、宜しくお願い致します。

【6747】Re:エクセル出力
発言  小僧  - 05/11/5(土) 18:00 -

引用なし
パスワード
   ▼Mino さん:
こんにちは。

>又、既に開いているファイルを検索して、
>(上書きの)指定したファイルと同じファイル名が存在していれば、
>処理を行わないようなロジックを組みましたが、
>上手くいきませんでした。

こちらの具体的な方法が記述されておりませんが、
指定の Excel ファイルを Open した後に
Workbook の ReadOnly プロパティの値を調べる事で
2重に開かれたかどうかを判断できると思います。


>更には、次にエクセルを起動しようとすれば、起動できなくなっています。
>(タスクマネージャーからEXCELを終了させれば、起動出来ましたが・・・)

こちらについては原因が 2 点考えられます。

1) 上位オブジェクトからの参照ができていない。
2) オブジェクトの解放がうまくいっていない。

コードがご提示されておりませんので、どこに原因があるかは不明ですが
大抵上記 2 点のどちらかができていない為の事象であると思われます。


>今、あるフォームにエクセル、CSV出力ボタンを設け、
>画面のデータをエクセルへ出力するようにしています。

CSV ファイルの出力であれば通常TransferText メソッドで行いますし、
わざわざ Excel で開く必要もないと思われますが…。

【6749】Re:エクセル出力
回答  YU-TANG WEB  - 05/11/5(土) 21:31 -

引用なし
パスワード
   こんにちは、YU-TANG です。

私の場合は、AleadyOpened という自作関数を使っています。
ご参考まで。

http://www.f3.dion.ne.jp/~element/msaccess/AcResTipsWarehouse1.html#TemplateExcelAuto

【6751】【解決】Re:エクセル出力
お礼  Mino  - 05/11/6(日) 11:41 -

引用なし
パスワード
   ▼小僧 さん:
▼YU-TANG さん:
ご回答、ありがとうございます。

結果としては、
AleadyOpenedの自作関数を使用する事で、
解決致しました。
YU-TANG さん、ありがとうございました。
又、小僧 さん、
色々なアドバイスをありがとうございます。
もしお分かりでしたら、教えて頂けないでしょうか?
説明の仕方が悪いかもしれませんが、ご了承下さい。


>指定の Excel ファイルを Open した後に
>Workbook の ReadOnly プロパティの値を調べる事で
>2重に開かれたかどうかを判断できると思います。

ロジックを見て頂くと分かりやすいかもしれません。
下記のようなロジックを追加してみました。

一つは、上書きを指定したファイルを検索して、
そのファイルは閉じるようにしてみました。
しかし「上書きしますか?」と上書きを指定したファイルだけは、
何故か検索されませんでした。
他に開いているファイルは、検索できましたが・・・。
  For Each Myfile In Exl.Workbooks
    If Myfile.Name = 「ファイル名」 Then
      Myfile.Close savechanges:=False
    End If
  Next Myfile

もう一つは、下記です。
よく分かりませんが、上手くいきませんでした。
(使用中となりませんでした)
  Exl.Workbooks.Open FileName:=「パス名+ファイル名」
  Exl.Workbooks(「ファイル名」).Activate
  If Exl.ActiveWorkbook.ReadOnly Then
    MsgBox "使用中"
    Exl.ActiveWorkbook.Close
    Set Exl = Nothing
    Exit Function
  End If

>>更には、次にエクセルを起動しようとすれば、起動できなくなっています。
>>(タスクマネージャーからEXCELを終了させれば、起動出来ましたが・・・)
>こちらについては原因が 2 点考えられます。
>1) 上位オブジェクトからの参照ができていない。
>2) オブジェクトの解放がうまくいっていない。
この場合は、エラーとなってしまうので、2) でしょうか。

分かっていないのですが、
コモンダイヤログを使用しており、
  ret = GetSaveFileName(OFN)
で、パス名+ファイル名を取得するようです。
ここでファイル保存先を指定する画面が開くのですが、
既存のファイルを指定すると、
「上書きしますか?」とメッセージが出ます。
「はい」にした時点で、
既存のファイル(既に開いているファイル)は、
どのような状態になるのでしょうか。
別でExcelが起動する気配はないのですが、
For Each に引っかからなかったので・・・。
(分かりにくい説明かもしれません。)

>CSV ファイルの出力であれば通常TransferText メソッドで行いますし、
>わざわざ Excel で開く必要もないと思われますが…。
申し訳ございません。
説明不足でした。
CSV は TransferText を使用しております。

【6753】Re:【解決】Re:エクセル出力
回答  小僧  - 05/11/6(日) 19:53 -

引用なし
パスワード
   ▼Mino さん:
こんばんは。
Excel のオートメーションって色々難しいですよね。
当方に解る範囲でしたら回答させて頂きます。

>他に開いているファイルは、検索できましたが・・・。
>  For Each Myfile In Exl.Workbooks
>    If Myfile.Name = 「ファイル名」 Then
>      Myfile.Close savechanges:=False
>    End If
>  Next Myfile


Excel のインスタンスを生成した直後に

Exl.Visible = True

と記述して、
該当の Excelファイル を開いたままステップ実行を行って確認されてみて下さい。

>  For Each Myfile In Exl.Workbooks

は 2 個目に起動された Workbook を参照しているので
「ファイル名」で指定された Excel が検索ができないのだと思われます。


>もう一つは、下記です。
>よく分かりませんが、上手くいきませんでした。
>(使用中となりませんでした)
>  Exl.Workbooks.Open FileName:=「パス名+ファイル名」
>  Exl.Workbooks(「ファイル名」).Activate
>  If Exl.ActiveWorkbook.ReadOnly Then
>    MsgBox "使用中"
>    Exl.ActiveWorkbook.Close
>    Set Exl = Nothing
>    Exit Function
>  End If

こちらについてですがステップ実行をした際に

>  Exl.Workbooks(「ファイル名」).Activate

の行で1つ目の Excel ファイルが Active 状態になってしまっていないでしょうか?
(すみません、当方未検証です。)

Sub ExcelCheck()
'要参照 Microsoft Excel x.x Object Library
Dim xName As String
Dim xlsApp As New Excel.Application
Dim xlsWkb As Excel.Workbook

  xName = "c:\Test.xls
  xlsApp.Visible = True
 
  Set xlsWkb = xlsApp.Workbooks.Open(xName)
  Debug.Print xlsWkb.ReadOnly
  
  xlsWkb.Close: Set xlsWkb = Nothing
  xlsApp.Quit: Set xlsApp = Nothing 
End Sub

上記コードで、xName で指定されたファイルが開かれている場合、閉じている場合の
両方で検証されてみて下さい。

Set xlsWkb = xlsApp.Workbooks.Open(xName)

と定義しているので、xlsWkb は後から開かれた Excel を確実に指しております。

すみません、長くなりますのでレスを分けます。

【6754】Re:【解決】Re:エクセル出力
回答  小僧  - 05/11/6(日) 20:05 -

引用なし
パスワード
   >>>更には、次にエクセルを起動しようとすれば、起動できなくなっています。
>>>(タスクマネージャーからEXCELを終了させれば、起動出来ましたが・・・)
>>こちらについては原因が 2 点考えられます。
>>1) 上位オブジェクトからの参照ができていない。
>>2) オブジェクトの解放がうまくいっていない。
>この場合は、エラーとなってしまうので、2) でしょうか。

1) の場合でもエラーが出ずに、タスクにマネージャーに Excel の残骸が出来る事があります。

先ほどご提示されたコードには特に 1) に該当する所はなさそうなのですが、

>  Exl.Workbooks.Open FileName:=「パス名+ファイル名」
>  Exl.Workbooks(「ファイル名」).Activate
>  If Exl.ActiveWorkbook.ReadOnly Then

この 3行目を
   If ActiveWorkbook.ReadOnly Then

などとしてしまうと、余計な Excel のインスタンスが形成されてしまい、
残骸が残ってしまう事となります。

当方が気になるのは 2) の方なのですが、

>    Exl.ActiveWorkbook.Close
>    Set Exl = Nothing
>    Exit Function

Exl.Visible = True

を指定して実行すると解りやすいと思うのですが、
Excel.Application は起動されたままになっていますね。

>    Exl.ActiveWorkbook.Close
'追加  
     Exl.Quit
>    Set Exl = Nothing

とすると、うまくインスタンスの解放ができると思います。
(コードの 1部しかご提示されておりませんので、他にも原因があるかもしれませんが)


既に手遅れとなってしまっているかもしれませんが、

>更には、次にエクセルを起動しようとすれば、起動できなくなっています。

とい状態を何回も繰り返していると、
Excel ファイルそのものがおかしくなってしまう事もあります…。
バックアップをこまめにとって大切なファイルを壊さないように気をつけて下さい。

【6755】Re:【解決】Re:エクセル出力
発言  小僧  - 05/11/6(日) 22:19 -

引用なし
パスワード
   ▼Mino さん:
ごめんなさい。蛇足ですが…。

>CSV は TransferText を使用しております。

CSV ファイルは Excel 以外のアプリケーションでも表示できます。
(メモ帳やフリーのテキストエディタなど)

検証してみたところ、メモ帳で開いている CSVファイル を
更に Excel で開いてみましたが読み取り専用にならない様でした。

ユーザがどのアプリケーションで開いていても対策のできるように
YU-TANG さんの ユーザ関数にあるように Open ステートメントを使った方が
良いかもしれませんね。

【6770】Re:【解決】Re:エクセル出力
お礼  Mino  - 05/11/8(火) 18:57 -

引用なし
パスワード
   ▼小僧 さん:
返事が遅くなり、申し訳ございません。

色々とご親切に教えて頂き、ありがとうございます。
大変、参考になりました。
しかし、その場では理解できても、
いざとなるとやはり難しいですね。

下記にてご報告致します。

>>他に開いているファイルは、検索できましたが・・・。
>>  For Each Myfile In Exl.Workbooks
>>    If Myfile.Name = 「ファイル名」 Then
>>      Myfile.Close savechanges:=False
>>    End If
>>  Next Myfile
>Excel のインスタンスを生成した直後に
>Exl.Visible = True
>と記述して、
>該当の Excelファイル を開いたままステップ実行を行って確認されてみて下さい。
>>  For Each Myfile In Exl.Workbooks
>は 2 個目に起動された Workbook を参照しているので
>「ファイル名」で指定された Excel が検索ができないのだと思われます。

確認しました。
確かに 2 個目を参照出来ましたが、
指定されたファイルは参照出来ませんでした。

>>よく分かりませんが、上手くいきませんでした。
>>(使用中となりませんでした)
>>  Exl.Workbooks.Open FileName:=「パス名+ファイル名」
>>  Exl.Workbooks(「ファイル名」).Activate
>>  If Exl.ActiveWorkbook.ReadOnly Then
>>    MsgBox "使用中"
>>    Exl.ActiveWorkbook.Close
>>    Set Exl = Nothing
>>    Exit Function
>>  End If
>こちらについてですがステップ実行をした際に
>>  Exl.Workbooks(「ファイル名」).Activate
>の行で1つ目の Excel ファイルが Active 状態になってしまっていないでしょうか?
>Sub ExcelCheck()
>'要参照 Microsoft Excel x.x Object Library
>Dim xName As String
>Dim xlsApp As New Excel.Application
>Dim xlsWkb As Excel.Workbook
>
>  xName = "c:\Test.xls
>  xlsApp.Visible = True
> 
>  Set xlsWkb = xlsApp.Workbooks.Open(xName)
>  Debug.Print xlsWkb.ReadOnly
>  
>  xlsWkb.Close: Set xlsWkb = Nothing
>  xlsApp.Quit: Set xlsApp = Nothing 
>End Sub
>上記コードで、xName で指定されたファイルが開かれている場合、閉じている場合の
>両方で検証されてみて下さい。

確認しました。
「Debug.Print xlsWkb.ReadOnly」は、
エラーになってしまいましたので、下記で行いました。
「Debug.Print xls.ActiveWorkbook.ReadOnly」
(・・・間違っていればご指摘下さい)

ファイルが開いている場合は、True
となり、「読取専用」で開きました。
ファイルが閉じている場合は、False
となり、ファイルが開きました。

これはなるほどと思いました。
これでオープン中かどうか、判別が出来るという事ですね。

他にも色々と学ばせて頂き、
又、検証までして頂き、
本当にありがとうございました。

【6771】Re:【解決】Re:エクセル出力
発言  YU-TANG WEB  - 05/11/8(火) 19:13 -

引用なし
パスワード
   念押しですが。

回答が付いているにもかかわらず今のところ放置状態の
マルチポストにも、フィードバックを忘れずお願いします。

【6786】Re:【解決】Re:エクセル出力
発言  Mino  - 05/11/10(木) 9:21 -

引用なし
パスワード
   ▼YU-TANG さん:
>念押しですが。
>
>回答が付いているにもかかわらず今のところ放置状態の
>マルチポストにも、フィードバックを忘れずお願いします。

上記の件ですが、
どういう意味かを教えて頂けないでしょうか?


 →答
  →礼

で終了だと思いますが、


 →答1
 →答2
  →礼(答1,2に対して)

では駄目という意味ですか?


 →答1
  →礼(答1に対して)
 →答2
  →礼(答2に対して)

にした方が良いですか?
フィードバックの意味がイマイチ判っていません・・・。
後、前者だとマルチポストになるんでしょうか?

何度も申し訳ないのですが、
宜しくお願い致します。

【6789】Re:【解決】Re:エクセル出力
回答  YU-TANG WEB  - 05/11/10(木) 12:47 -

引用なし
パスワード
   こんにちは、YU-TANG です。

> >回答が付いているにもかかわらず今のところ放置状態の
> >マルチポストにも、フィードバックを忘れずお願いします。
>
> 上記の件ですが、
> どういう意味かを教えて頂けないでしょうか?

マルチポストとは、複数の掲示板やメーリングリスト、ニュースグループ
等に、同一内容の投稿を行うことを指します。

具体例を挙げるなら、たとえば Access 会議室と Access VBA 質問箱に
同一内容の投稿を行った場合、マルチポストになります。

その後、両方の掲示板でそれぞれレスが付き、Access VBA 質問箱で
クローズしたとします。
この場合は、Access 会議室にも結果説明のレスを付ける必要があります。
これは単に「解決しました」とか「ありがとうございました」という
レベルのレスを指しているわけではありません。
過去ログを参照するユーザーと ROM ユーザー、回答者のために、
どのように解決したか、具体的に報告(フィードバック)する必要が
あります。
言い換えるなら、同じ問題を抱えた誰かが後で Access 会議室の過去ログ
を読んだときに、そこでのやり取りのみから あなたの取った解決方法を
知ることが可能であることを保証する必要がある、ということです。
これは無償で掲示板を利用したことに伴う一種の義務と捉えていただいて
結構です。

この義務がしばしば忘れられるケースがあるため、「念押し」をしたと
いうことです。

なお、上記のような対応が許されるのは、マルチポストを容認している
掲示板同士に限られるため、事前に各媒体の FAQ や参加規程、利用条件
等を確認する必要があります。

1516 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078229
(SS)C-BOARD v3.8 is Free