- - PR -
ExcelVBAで.ActiveVBProject.References.AddFromFileもしくは.Removeすると同じプロシージャ内で.Showした
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 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 |
|
投稿日時: 2006-12-13 12:57
申し訳ありません。
題名が長すぎたためか,題名の語尾が切れてしまっていました。 下記に題名を改めて書いておきます。 ExcelVBAで Application.VBE.ActiveVBProject.References.AddFromFile もしくは Application.VBE.ActiveVBProject.References.Remove すると 同じプロシージャ内で.Showしたユーザフォームが 勝手に消えてしまう。 です。少しでも,ヒントか何かでもお持ちの方がいましたら, 書込をお願いします。 |
|
投稿日時: 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はきえてしまいました。 |
|
投稿日時: 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() プロシージャが終了直後に ログインフォームが表示されることになり, 私の望み通りの動作をさせることができました。 ともに考えてくださった方,ありがとうございました。 また,この方法について,問題がある等の情報をお持ちの方が いましたら,ぜひ書き込んでください。 よろしくおねがいします。ありがとうございました。 |
|
投稿日時: 2006-12-13 18:53
ちなみに解決に至った情報源は,次のサイトです。
http://park7.wakwak.com/cgi-bin/sbox/~efc21/wwwlng.cgi?print+200602/06020165.txt このサイトに,似たような現象が記述されていましたので, OnTimeの部分をまねてやってみたのです。 |
|
投稿日時: 2006-12-14 11:26
さらに報告です。
問題となっていたWorkbook_Open()プロシージャ内で変数にある値を格納し その変数を別のプロシージャで使おうとすると,変数の中身がクリアになっていました。 この現象から,より今回の問題の原因がわかってきつつあります。 「参照設定」の変更をマクロで行ったプロシージャが終了すると同時に, いったんマクロで格納した変数の値やフォームがクリアになる ということです ですから,「さんしょうせってい」を行ったプロシージャが終了直後に 変数を格納すれば,問題なく動作しました。 |
1