tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルAccessVBAでエクセルが解放がされない件
記事No11221
投稿日: 2014/02/27(Thu) 14:15
投稿者まほろば
初めまして、まほろばといいます。
VBA歴5年程度の日曜プログラマーです。VB6.0での開発も少しだけ経験がありますが、VB6.0、VBAとも完全にわかっているわけではございませんので質問させていただきたいです。

今、エクセルのシートの時系列の売上データをAccessのテーブルに追加するVBAを作っています。
Access側のコマンドボタンのクリックで下記のVBAを動かそうと思っていました。
テーブルにはエクセルのシートのデータは正しく追加されますが、最後にエクセルが解放されずにプロセスに残ったままになってしまいます。
当サイトを参考にいろいろ調べてやってみたのですが、どうしても解放されず行き詰っています。
本来はVBの掲示板だと理解していますが、VBAでの質問で申し訳ございません。
どうすればうまくいくのか、ご指導よろしくお願いいたします。

環境は、
Windows7ultimate 32bit版 Excel2013,Access2013
です。



(参照設定)
Visual Basic For application
OLE Automation
Microsoft Access 14.0 Object Library
Microsoft ActiveX Data Objects 2.8 Library
Microsoft Excel 14.0 Object Library
Microsoft Windpws Common Controls-2 6.0

(コード)
Private Sub 追加更新日次売上データ()


Dim conAcc As ADODB.Connection
Dim rsAcc As ADODB.Recordset

Dim myDate, myExDate, myAccDate As Date
Dim sql As String
Dim rowCount  As Long


Dim filePath  As String

Dim xlApp As Excel.Application
Dim xlBooks As Excel.Workbooks
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Dim myRange As Object

Dim rsTbl As New ADODB.Recordset
Dim conTbl As ADODB.Connection

    
'Sale_Tの最新の日付を取得
    Set rsAcc = New ADODB.Recordset
    Set conAcc = Application.CurrentProject.Connection
    
  
    
    ' SQL文作成
    sql = "SELECT * FROM Sale_T ORDER BY [Sale_T].日付; "
    rsAcc.Open sql, conAcc, adOpenDynamic, adLockOptimistic, adCmdText


rsAcc.MoveLast

myAcDate = rsAcc("日付").Value      'Sale_Tの最新日付

rsAcc.Close
conAcc.Close

Set rsAcc = Nothing
Set conAcc = Nothing

'//////////////////////////////////////////////////////////////////////////////
'エクセルのパス

    filePath = "D:\売上\日次売上\SalesDay.xlsm"

'Excelブックオブジェクト
    Set xlApp = CreateObject("Excel.Application")
    Set xlBooks = xlApp.Workbooks
    Set xlBook = xlBooks.Open(filePath)     'ファイルパスのExcelブックを開く

'ワークシートオブジェクト
    Set xlSheet = xlBook.Worksheets(1)      '1枚目のワークシート
   xlApp.Visible = True

'ワークシート内レコードの最新日付を取得する
    
    rowCount = xlSheet.Range("A1").End(xlDown).Row
    
    xlSheet.Select
    Set myRange = xlSheet.Range(xlSheet.Cells(1, 1), xlSheet.Cells(rowCount, 1))
    myExDate = xlApp.Application.WorksheetFunction.Max(myRange)  'IR(20).xlsmの最新日付

    myAccDate = Format(myAcDate, "Short Date")
    myExDate = Format(myExDate, "Short Date")

    If myAccDate >= myExDate Then  'Accessテーブルの最新日付よりエクセルの最新日付が遅ければExitする
      
       'Excelを閉じる
      
       Set myRange = Nothing
      
       Set xlSheet = Nothing
      
       xlBook.Saved = True
       xlBook.Close
       Set xlBook = Nothing
       Set xlBooks = Nothing
      
       xlApp.Quit
       Set xlApp = Nothing


   MsgBox ("追加データはありません。")
      
    Exit Sub

   
    Else

   以下省略

[ツリー表示へ]
タイトルRe: AccessVBAでエクセルが解放がされない件
記事No11222
投稿日: 2014/02/27(Thu) 16:26
投稿者魔界の仮面弁士
> Microsoft Windpws Common Controls-2 6.0
これは Access 2013 付随のコンポーネントではありませんが、大丈夫でしょうか。
利用には、開発ライセンス(≠ランタイムライセンス)が必要となります。

ちなみに OWC、MODI、MSCAL も、現行の Access には付属していません。


> filePath = "D:\売上\日次売上\SalesDay.xlsm"
マクロブックをお使いですね。
空の xlsx などを用いて検証してみてください。

VBA 側のコードに、対象オブジェクトが曖昧な記述が含まれていた場合、
それが原因で、外部からの呼び出し時に解放漏れを起こすケースがあるためです。


> Dim myDate, myExDate, myAccDate As Date
この場合、Date 型となるのは myAccDate だけです。

前の 2 つは、既定のデータ型(特に指定がなければ Variant)として
解釈されますのでご注意ください。

もし、3 つともDate 型としたいのであれば、
 Dim myDate As Date, myExDate As Date, myAccDate As Date
のように記述する必要があります。すでに御存知かも知れませんが。


> Dim rsTbl As New ADODB.Recordset
ここで New を付与するべきではありません。


> rsAcc.Open sql, conAcc, adOpenDynamic, adLockOptimistic, adCmdText
adOpenDynamic タイプとは珍しいですね。
動的カーソルって使いにくくないですか?


> Set xlApp = CreateObject("Excel.Application")
参照設定しているのなら、= New Excel.Application の方が良いと思います。

逆に、レイトバインドでコーディングしたいということであれば、
Excel への参照設定をしない方が、むしろ安全かと思います。


> myExDate = xlApp.Application.WorksheetFunction.Max(myRange)  'IR(20).xlsmの最新日付
この場合、xlApp.Application.WorksheetFunction は冗長だと思いますよ。

xlApp と xlApp.Application と xlApp.Application.Application は、
すべて同じインスタンスを意味しますし。

[ツリー表示へ]
タイトルRe^2: AccessVBAでエクセルが解放がされない件
記事No11224
投稿日: 2014/02/27(Thu) 17:46
投稿者まほろば
早速のご返答ありがとうございます!

> > Microsoft Windpws Common Controls-2 6.0
> これは Access 2013 付随のコンポーネントではありませんが、大丈夫でしょうか。

ライセンス関係のことでしょうか?
この辺無頓着になっていましたので改めて見直したいと思います。
書き忘れましたが、環境は、、、
自宅 Windows7(ultimate)32bit版 Access2013 Excel2030
会社 Windows7(Pro)32bit版 Access2010 Excel2010

でした。
>
> > filePath = "D:\売上\日次売上\SalesDay.xlsm"
> マクロブックをお使いですね。
> 空の xlsx などを用いて検証してみてください。

SalesDay_.xlsxでやってみましたが、やはり解放されていませんでした。

>  Dim myDate As Date, myExDate As Date, myAccDate As Date
> のように記述する必要があります。すでに御存知かも知れませんが。

そうでした。以後気をつけます(汗

> > Dim rsTbl As New ADODB.Recordset
> ここで New を付与するべきではありません。

これもそうですね。つい手癖でやってしまいます(汗

>
> > rsAcc.Open sql, conAcc, adOpenDynamic, adLockOptimistic, adCmdText
> adOpenDynamic タイプとは珍しいですね。
> 動的カーソルって使いにくくないですか?

これも書き直します。あまり意識していませんでした。

>
> > Set xlApp = CreateObject("Excel.Application")
> 参照設定しているのなら、= New Excel.Application の方が良いと思います。
>
> 逆に、レイトバインドでコーディングしたいということであれば、
> Excel への参照設定をしない方が、むしろ安全かと思います。

今まで遅延バインディングというものをやったことがありませんでしたので一度勉強しなおしてやってみます。


> > myExDate = xlApp.Application.WorksheetFunction.Max(myRange)  'IR(20).xlsmの最新日付
> この場合、xlApp.Application.WorksheetFunction は冗長だと思いますよ。

はい。これも書き直しました。

本題以外でもいろいろと勉強になりました。
ご指摘の点を直したうえで再度VB6.0の方へ移り質問させていただきたいと思います。
ありがとうございました。

[ツリー表示へ]
タイトルRe: AccessVBAでエクセルが解放がされない件
記事No11223
投稿日: 2014/02/27(Thu) 16:29
投稿者VBレスキュー(花ちゃん)
こちらは、.NET 系専用の Visual Basic の掲示板になっておりますので、VBA に関しては、
となりの VB6.0 用の掲示板の方にお願いします。


>    以下省略

の部分のコードはどうなっているのでしょうか?(解放処理等)
それとも省略された部分のコードを通過した場合は、キチンと終了しているという事でしょうか?

順番にコメントアウトしながらどの作業をしなかったらキチンと終了するかを調べて見て下さい。

[ツリー表示へ]
タイトルRe^2: AccessVBAでエクセルが解放がされない件
記事No11225
投稿日: 2014/02/27(Thu) 17:51
投稿者まほろば
> こちらは、.NET 系専用の Visual Basic の掲示板になっておりますので、VBA に関しては、
> となりの VB6.0 用の掲示板の方にお願いします。
>
>
> >    以下省略
>
> の部分のコードはどうなっているのでしょうか?(解放処理等)
> それとも省略された部分のコードを通過した場合は、キチンと終了しているという事でしょうか?
>
> 順番にコメントアウトしながらどの作業をしなかったらキチンと終了するかを調べて見て下さい。

早速のご対応ありがとうございます!
省略した部分においても解放はされませんでした。
省略部分も含めて再度VB6.0掲示板の方へ投稿させていただきます。

[ツリー表示へ]
タイトルRe: AccessVBAでエクセルが解放がされない件
記事No11227
投稿日: 2014/02/27(Thu) 23:53
投稿者まほろば
1.
>環境依存の問題が生じている可能性も考えられます
すみません、自宅の方はExcel2013と2010が共存していることを忘れていました。
その他アドインや自動マクロの類はありません。

2.
>Excel.Application だけを 起動→表示→終了→Nothing させるコードを試してみてください
これもテストしましたが依然解放されていませんでした。

3.
>myAccDate = Format(myAcDate, "Short Date")
右辺のmyAcDateはmyAccDateの投稿するときのタイプミスです。お手数かけてすみませんでした。

4.
>原因箇所を特定してみてください。
いろいろとテストするうち下記のような結果になりました。
書き換えたのは「Excelの参照設定の有無」と「Set xlApp =〜」の2か所です。
結果は

(1)Excelの参照設定あり
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
解放される


(2)Excelの参照設定なし
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application") 

rowCount = mysheet.Range("A1").End(xlDown).Row
(反転)xlDown
「コンパイルエラー 変数が定義されていません。」
となったので

rowCount=600

としてテスト
解放される


(3)Excelの参照設定あり
Dim xlApp As Object
Set xlApp = New Excel.Application
解放される


(4)Excelの参照設定なし
Dim xlApp As Object
Set xlApp = New Excel.Application
(反転)New Excel.Application
「コンパイルエラー ユーザー定義型は定義されていません。」


(2)は途中のエラーはあったものの結果的に解放されていましたが、これは最初に投稿したコードだと思うのです。
その時は途中のエラーもなく、最後に解放されない状態であったのですが、、、。
ちょっと不思議な気分です。
違いはというと参照設定を外すことなくテストしていたことです。今回投稿してみて初めて参照設定をはずして再度設定してテストしてみてうまく解放されたということは、何かコード以外の原因があるのかなぁとか思っています。
ともあれまずはうまくいきましたので当面の間これで続けていきます。
魔界の仮面弁士様、花ちゃん様、いろいろたくさんのご指導ありがとうございました。

[ツリー表示へ]
タイトルRe^2: AccessVBAでエクセルが解放がされない件
記事No11228
投稿日: 2014/02/27(Thu) 23:55
投稿者まほろば
すみません。
また間違えてこちらに投稿してしまいました。
改めてVB6.0の方に投稿させていただきます。

[ツリー表示へ]