- PR -

ExcelVBAで.ActiveVBProject.References.AddFromFileもしくは.Removeすると同じプロシージャ内で.Showした

1
投稿者投稿内容
am3125yy
会議室デビュー日: 2006/04/12
投稿数: 9
お住まい・勤務地: 沖縄県
投稿日時: 2006-12-13 12:37
ExcelVBAでスクリプトを書いているam3125yyです。
問題となっているプロシージャを下記に記します。

'*****************************************
Private Sub Workbook_Open()
'*****ADO削除******************************
Dim i As Integer
Dim myLib
Dim sLib As Variant
sLib = _
Array( _
"Microsoft ActiveX Data Objects 2.0 Library", _
"Microsoft ActiveX Data Objects 2.1 Library", _
"Microsoft ActiveX Data Objects 2.5 Library", _
"Microsoft ActiveX Data Objects 2.6 Library", _
"Microsoft ActiveX Data Objects 2.7 Library", _
"Microsoft ActiveX Data Objects 2.8 Library")

'現在設定されているADOを削除する。
With Application.VBE.ActiveVBProject
For i = 0 To 5 Step 1
For Each myLib In .References
If myLib.Description = sLib(i) Then
.References.Remove myLib
End If
Next
Next i
End With

'******ADO追加*****************************
'■ADOの最新が2.8の場合
With Application.FileSearch
.NewSearch
.LookIn = "C:\Program Files\Common Files\System\ado"
.Filename = "msado15.dll"
If .Execute(SortBy:=msoSortByFileName, SortOrder:=msoSortOrderDescending) > 0 Then
Application.VBE.ActiveVBProject.References.AddFromFile .FoundFiles(1)
GoTo ADD_OK
End If

'■ADOの最新が2.0〜2.7の場合
.NewSearch
.LookIn = "C:\Program Files\Common Files\System\ado"
.Filename = "msado*.tlb"
If .Execute(SortBy:=msoSortByFileName, SortOrder:=msoSortOrderDescending) > 0 Then
Application.VBE.ActiveVBProject.References.AddFromFile .FoundFiles(1)
GoTo ADD_OK
End If
End With

'■ADOがコンピュータに用意されていない場合
MsgBox "今のこのコンピュータの状態では,本システムを使うことができません。" & vbCrLf _
& "このコンピュータにADOライブラリを追加する必要があります。"
'Application.Quit

ADD_OK:

login_form.StartUpPosition = 2
login_form.Show vbModeless
MsgBox "ここは?10"
End Sub
'*****************************************

上記が問題となっているプロシージャのスクリプトです。
このlogin_form.Showによって,いったんは表示されるものの,
MsgBox "ここは?10"で「OK」をクリックすると,
login_formが消えてしまいます。

また,上記のスクリプトのうち,次の2行
Application.VBE.ActiveVBProject.References.AddFromFile .FoundFiles(1)

.References.Remove myLib
この2行をコメントアウトすると,きちんと
login_form.Showされて,表示された状態が保たれたまま,
プロシージャの処理が終わります。

上記のように,VBEの「ツール」→「参照設定」の
ADOの最新ライブラリにチェックを入れるスクリプトを作ったのですが,
このスクリプトを実行完了後に,このlogin_formを.Showしたいのです。
対応等,ご存じの方いらっしゃいましたら,教えていただけないでしょうか?



なお,login_form内のスクリプトもいちおう下記に記しておきます。
Option Explicit

Private Sub UserForm_Initialize()
Dim Tuki As Integer
Dim Nen As Integer
loginButton.Enabled = False
Tuki = Month(Date)
Nen = Year(Date)
'■■年度を出力したいので、1〜3月の場合は(年−1)年度とする処理
If 1 <= Tuki And Tuki <= 3 Then
NendoBox.Text = Nen - 1 '年度にしたいので1〜3月の場合は(年−1)年度とする
Else
NendoBox.Text = Nen '年を取ってきてるだけで年度となる
End If
End Sub
'■工夫した点
'@年と月を用いて、年度出力ができる処理を施した


Private Sub IDbox_Change()
If IDbox.TextLength > 0 Then
loginButton.Enabled = True
End If
End Sub

Private Sub quitButton_Click()
MsgBox "このエクセルファイルを閉じます"
Application.Quit
End Sub

Private Sub loginButton_Click()

Dim cn_login As New ADODB.Connection 'Connectionオブジェクト 変数宣言
Dim rs_login As New ADODB.Recordset 'Recordsetオブジェクト 変数宣言
Dim sql_login As String '選択用のSQL文 変数宣言
Dim id_login As String 'ログインIDを格納する変数
Dim pass_login As String 'パスワードを格納する変数
Dim sql_tannin As String

LoginID_G = IDbox.Text
Nendo_G = NendoBox.Text

'ユーザがブックを表示していた場合にボタンクリックで再度最小化する
Application.WindowState = xlMinimized

'再度「シートの保護」を設定
Sheet2.Protect Password:="hogehoge", contents:=True, UserInterfaceOnly:=True
Sheet7.Protect Password:="hogehoge", contents:=True, UserInterfaceOnly:=True

Sheet1.Protect Password:="hogehoge", contents:=True, UserInterfaceOnly:=True
Sheet4.Protect Password:="hogehoge", contents:=True, UserInterfaceOnly:=True
Sheet6.Protect Password:="hogehoge", contents:=True, UserInterfaceOnly:=True


'接続情報
cn_login.ConnectionString = DBInfor

'ConnectionオブジェクトのOpenメソッド
cn_login.Open
'データベース内のIDとパスワードに一致するか確認(選択用のSQL文)
sql_login = "EXECUTE LoginCertification @LoginID='" & LoginID_G & _
"', @Passswd='" & PassBox.Text & "', @Nendo=" & Nendo_G

'RecordsetオブジェクトのOpenメソッド
rs_login.Open sql_login, cn_login

'■■この分岐がログイン認証とデータ出力制御になっています。ストアドプロシージャ使用■■■■
If rs_login!LC = "Failure" Then
'ログインの失敗
MsgBox "IDもしくはパスワードが間違っているため,ログインできません。エクセルを終了します"
Sheet5.Visible = xlSheetVisible
login_form.Hide
Application.Quit
Else
'イベント停止
Application.EnableEvents = False
If rs_login!MGR = "MGR" Then
'管理者用シート表示するプロシージャの実行
Call Module3.MGR_Sheet(xlSheetVisible)
'管理者用シートのデータ消去を実行
Call Module3.Sheet1ValueDelete
Call Module3.Sheet4ValueDelete
Call Module3.Sheet6ValueDelete
'管理者用シートにデータを取ってくる
Call Module3.DBTeacherSelect 'Sheet1だよ
Call Module3.DBkyuuStudentSelect 'Sheet4だよ
Call Module3.DBSelect1Sheet6 'Sheet6だよ
Else
'管理者用シートを非表示にするプロシージャの実行
Call Module3.MGR_Sheet(xlSheetVeryHidden)
End If
Select Case rs_login!LC
Case "Nothing"
'管理者で担任じゃない人に保護シートを見せない
If rs_login!MGR = "MGR" Then
Sheet5.Visible = xlSheetVeryHidden
Else
'ログイン保護シートを表示するプロシージャの実行
Sheet5.Visible = xlSheetVisible
'担任用シートを非表示にするプロシージャの実行
Call Module3.LC_Sheet(xlSheetVeryHidden)
End If
Case "TanNoDt"
'担任用シートを表示するプロシージャの実行
Call Module3.LC_Sheet(xlSheetVisible)
'担任用シートのデータ消去を実行
'■Sheet2(入力画面1)のデータを消去命令
Call Module3.Sheet2ValueDelete
'■Sheet7(印刷画面1)のデータを消去命令
Call Module3.Sheet7ValueDelete
'ログイン保護シートを非表示にする
Sheet5.Visible = xlSheetVeryHidden
Case "TanYesDt"
'担任用シートを表示するプロシージャの実行
Call Module3.LC_Sheet(xlSheetVisible)
'担任用シートのデータ消去を実行
'■Sheet2(入力画面1)のデータを消去命令
Call Module3.Sheet2ValueDelete
'■Sheet7(印刷画面1)のデータを消去命令
Call Module3.Sheet7ValueDelete
'担任用シートにデータを取ってくる。
'Sheet7印刷画面にデータベースから担任用のコンボボックスを作成する
Call Module3.DBMakeCombobox1(Sheet7)
'Sheet2入力画面1にデータベースから取ってくる
Call Module3.DBSelect1(Sheet2)
'ログイン保護シートを非表示にする
Sheet5.Visible = xlSheetVeryHidden
End Select

'ユーザ入力とデータ保存の時刻を一致させる
DBkoushintime_G = SCkoushintime_G
DBkoushintimeZen_G = SCkoushintimeZen_G
'出力処理用のレコードセットを切断
rs_login.Close
Set rs_login = Nothing


login_form.Hide
Unload login_form
Application.WindowState = xlMaximized
'イベント再開
Application.EnableEvents = True
MsgBox "正しくログインできました"
End If

'切断

cn_login.Close
Set cn_login = Nothing '2行目で宣言した変数のメモリ領域の解放

End Sub
'*******************************************************************************


'******************************************************************************************
'×ボタンを押されたら,Excel自体が落ちる設定
'******************************************************************************************
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Application.Quit
End If
End Sub
am3125yy
会議室デビュー日: 2006/04/12
投稿数: 9
お住まい・勤務地: 沖縄県
投稿日時: 2006-12-13 12:57
申し訳ありません。
題名が長すぎたためか,題名の語尾が切れてしまっていました。
下記に題名を改めて書いておきます。

ExcelVBAで
Application.VBE.ActiveVBProject.References.AddFromFile
もしくは
Application.VBE.ActiveVBProject.References.Remove
すると
同じプロシージャ内で.Showしたユーザフォームが
勝手に消えてしまう。

です。少しでも,ヒントか何かでもお持ちの方がいましたら,
書込をお願いします。
am3125yy
会議室デビュー日: 2006/04/12
投稿数: 9
お住まい・勤務地: 沖縄県
投稿日時: 2006-12-13 17:05
追加報告します。

【追加報告1】
Application.VBE.ActiveVBProject.References.Remove
で削除する参照設定をADOではなく他の項目を試してみましたが、
それでも同様にlogin_formというUserFormはきえてしまいました。

【追加報告2】
Call Module3.REMOVE_VBAProject
Call Module3.ADD_VBAProject
の後に、
Sheet5.Activate
を入れてみましたが、それでも
同様にlogin_formというUserFormはきえてしまいました。
am3125yy
会議室デビュー日: 2006/04/12
投稿数: 9
お住まい・勤務地: 沖縄県
投稿日時: 2006-12-13 18:50
大変お騒がせしました。
望み通りの動作をさせることに成功しました。
その方法を下記に記します。

*****************************************************
1.ログインフォーム表示するプロシージャを作成する。
Sub Login_form_show()
login_form.StartUpPosition = 2
login_form.Show vbModeless
End Sub

2.このプロシージャをCallではなく,OnTimeで呼び出す
Call Module3.REMOVE_VBAProject
Call Module3.ADD_VBAProject
Application.OnTime Now, "Module3.Login_form_show"
*****************************************************

これにより,Workbook_Open() プロシージャが終了直後に
ログインフォームが表示されることになり,
私の望み通りの動作をさせることができました。

ともに考えてくださった方,ありがとうございました。
また,この方法について,問題がある等の情報をお持ちの方が
いましたら,ぜひ書き込んでください。
よろしくおねがいします。ありがとうございました。
am3125yy
会議室デビュー日: 2006/04/12
投稿数: 9
お住まい・勤務地: 沖縄県
投稿日時: 2006-12-13 18:53
ちなみに解決に至った情報源は,次のサイトです。

http://park7.wakwak.com/cgi-bin/sbox/~efc21/wwwlng.cgi?print+200602/06020165.txt

このサイトに,似たような現象が記述されていましたので,
OnTimeの部分をまねてやってみたのです。
am3125yy
会議室デビュー日: 2006/04/12
投稿数: 9
お住まい・勤務地: 沖縄県
投稿日時: 2006-12-14 11:26
さらに報告です。

問題となっていたWorkbook_Open()プロシージャ内で変数にある値を格納し
その変数を別のプロシージャで使おうとすると,変数の中身がクリアになっていました。

この現象から,より今回の問題の原因がわかってきつつあります。
「参照設定」の変更をマクロで行ったプロシージャが終了すると同時に,
いったんマクロで格納した変数の値やフォームがクリアになる
ということです

ですから,「さんしょうせってい」を行ったプロシージャが終了直後に
変数を格納すれば,問題なく動作しました。
1

スキルアップ/キャリアアップ(JOB@IT)