CreateEventProc()2回目実行するとEXCELが落ちる

このQ&Aのポイント
  • EXCELが落ちてしまう現象が解決できずに困っています。詳しい方がいらっしゃったら教えて下さい。
  • vInsertButton()の下側をコメントアウトしてボタンを1つだけ配置すると正常に処理が完了します。vInsertButton()の処理に問題がありましたら教えていただけませんでしょうか?
  • CreateEventProc()あたりに問題がありそうなのですが分かりません。VISTA&EXCEL2007では、この現象は発生しませんでした。WinXP&EXCEL2000とWinXP&EXCEL2003でこの現象が再現しました。OfficeUpdateでは最新と表示されました。
回答を見る
  • ベストアンサー

CreateEventProc()2回目実行するとEXCELが落ちる

EXCELが落ちてしまう現象が解決できずに困っています。 詳しい方がいらっしゃったら教えて下さい。 データ数分ボタンを配置したいので、No.321427の質問を参考にコードを書きました。 EXCEL VBAで下記のコードのtest1()を実行するとEXCELが落ちてしまいます。 ちなみに、vInsertButton()の下側をコメントアウトして ボタンを1つだけ配置すると正常に処理が完了します。 vInsertButton()の処理に問題がありましたら教えていただけませんでしょうか? CreateEventProc()あたりに問題がありそうなのですが分かりません。 VISTA&EXCEL2007では、この現象は発生しませんでした。 WinXP&EXCEL2000とWinXP&EXCEL2003でこの現象が再現しました。 OfficeUpdateでは最新と表示されました。 よろしくお願いします。 ------------------------------------------------------------------------------------------------------- ' 設定 ' VBEのツール→参照設定で、 Microsoft Visual Basic Editor for Application Extensibility にチェックして下さい。 Option Explicit Private Sub test1() ' ボタン追加 Call vInsertButton("button1", 2, 1) Call vInsertButton("button2", 2, 2) End Sub ' ボタン追加 Private Sub vInsertButton(ByVal strButtonName As String, ByVal iRow As Integer, ByVal iCol As Integer) ' ボタン追加 Dim objButton As OLEObject With Worksheets("Sheet1") Dim clButtonRange As Range Set clButtonRange = .Range(.Cells(iRow, iCol), .Cells(iRow, iCol)) Set objButton = .OLEObjects.Add(classtype:="Forms.CommandButton.1", _ link:=False, displayasicon:=False, _ Left:=clButtonRange.Left, Top:=clButtonRange.Top, _ Width:=clButtonRange.Width, Height:=clButtonRange.Height) objButton.Object.TakeFocusOnClick = False objButton.Object.Caption = strButtonName End With 'クリックイベントコード追加 With ThisWorkbook.VBProject.VBComponents("Sheet1").CodeModule Dim iLineCounter As Long iLineCounter = .CreateEventProc("Click", objButton.Name) .InsertLines iLineCounter + 1, "MsgBox ""abc""" End With End Sub -------------------------------------------------------------------------------------------------------

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんにちは。 >VISTA&EXCEL2007では、この現象は発生しませんでした。 バージョンに関わらず、そのコードでは、上手くできているとは思えません。一つのオブジェクトを入れるだけのコードだったはずです。 あくまでも、個人が使うものだと了解しています。もしも、他者の環境で使う場合は、フォームツールのほうが安全かと思います。(決して、ハングするのが原因ではありませんが、セキュリティの関係で、Application Extensibilityを入れる方法が好まれません。) さて、コードのほうですが、原因は、イベントコード追加の時に、VBEditor に書き込むときに、Sheet1 モジュールが、Activate してしまい、その上にコードが走ろうとするので、ハングするのではないかと思います。 以下の場合は、二つに別けて、Control名を確保して、モジュールに一気にコードを書けばよいと思います。 '----------------------------------------- Dim arNames(1) As String Dim i As Long Private Sub Main1() i = 0 Erase arNames() Call vInsertButton("button1", 2, 1) Call vInsertButton("button2", 2, 2) Call AddLines End Sub Private Sub vInsertButton(ByVal strButtonName As String, ByVal iRow As Integer, ByVal iCol As Integer)   ' ボタン追加 Dim clButtonRange As Range Dim objButton As OLEObject   With Worksheets("Sheet1")     Set clButtonRange = .Range(.Cells(iRow, iCol), .Cells(iRow, iCol))     Set objButton = .OLEObjects.Add(classtype:="Forms.CommandButton.1", _     link:=False, displayasicon:=False, _     Left:=clButtonRange.Left, Top:=clButtonRange.Top, _     Width:=clButtonRange.Width, Height:=clButtonRange.Height)     objButton.Object.TakeFocusOnClick = False     objButton.Object.Caption = strButtonName   End With   arNames(i) = objButton.Name   Set objButton = Nothing   i = i + 1 End Sub Sub AddLines()   'クリックイベントコード追加    Dim iLineCounter As Long    Dim objName As Variant   For Each objName In arNames   With ThisWorkbook.VBProject.VBComponents("Sheet1").CodeModule     iLineCounter = .CreateEventProc("Click", objName)     .InsertLines iLineCounter + 1, "MsgBox ""abc"""   End With   Next objName End Sub

sola32
質問者

お礼

無事動きました。 ありがとうございました。

関連するQ&A

  • VB.net 2010 DataGrigView

    VBでDataGridViewを使用して表の入力処理をして居ます。 入力内容が数字で無い時はエラー表示をして、セルのフォーカスをエラーセルに戻そうとして居ます。 実際にプログラムを組んだのですが、エラー時にセルのフォーカスが元に戻らす、エラーで無い時と同じ様に次の行に行ってしまいます。 エラー時にRow、Columnのアドレスを保存して置き、ボタンでそのRow、Columnの場所にセルのフォーカスを当てると、その位置のセルにフォーカスが当たります。 コーディング上は全く同じですが、同一処理内ではフォーカスの設定は出来ないものでしょうか。 試しに間にApplication.DoEvents()を入れてみましたが結果は同じでした。 どなたかこの現象を解決出来る方法が分かる方、若しくはDataGridViewではこの様な事は出来ない理由をご存知の方、お教え下さる様お願い致します。 ‘CellEndEdit割り込み処理 Private Sub dgvTst_CellEndEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvTst.CellEndEdit Dim iVal As Integer Dim sWrk As String sWrk = dgvTst.CurrentCell.Value ‘セルの値をワークに If subChkDec(sWrk) = False Then '数字か調べる。 MsgBox("Error") ‘数字で無い時、エラー表示 iRow = dgvTst.CurrentCell.RowIndex ‘Rowアドレス取得 iCol = dgvTst.CurrentCell.ColumnIndex ‘Columnアドレス取得 lblRow.Text = iRow.ToString("D") ‘デバックの為にRow表示 lblCol.Text = iCol.ToString("D") ‘デバックの為にColumn表示 Application.DoEvents() dgvTst.CurrentCell = dgvTst.Rows(iRow).Cells(iCol) ‘RowとColumnを指定してセル位置変更したつもり、フォーカスは入力したセルの下に移動する。 End If End Sub ‘ボタンでの割り込み処理。 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click dgvTst.CurrentCell = dgvTst.Rows(iRow).Cells(iCol) ‘同じ処理をボタンの割り込みで行うと指定した(エラーとなった)所にフォーカスが移る。 End Sub

  • 【Excel VBA】コマンドボタンの選択&移動

    Excel2003を使用しています。 以前、こちらで教えていただいて、1クリックで1ページ分移動するコマンドボタンを作成しました。 左クリックでDown、右クリックでUpし、Sheet2モジュールに下記のコードを記述しています。 このコマンドボタン自体を選択して、現在配置している場所(セル上)から移動させたい場合、どのように操作すればいいでしょうか? 右クリック、左クリック両方にページ移動が設定されているため、コマンドボタン自体を選択することができません…。 マクロが動作しないよう、一旦、コードを削除して、ボタンをクリックしてみたのですが、選択状態になりませんでした。 よろしくお願いします。 ------------------------------------------------------- Private Sub CommandButton1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)  '左クリック-進む-Down  '右クリック-戻る-Up   CommandButton1.Caption = "左-Down, 右-Up"   Dim WinTop As Long   Dim i As Long   i = Int((ActiveCell.Row) / 26) + 1   If Button = 1 Then     Application.Goto Cells(i * 26 + 1, 1), True   ElseIf Button = 2 Then     If i > 1 Then       Application.Goto Cells((i - 2) * 26 + 1, 1), True     End If   End If    WinTop = ActiveWindow.VisibleRange.Top + 2 '(2は縦の位置調整)    CommandButton1.Top = WinTop End Sub

  • テニス(ダブルス)乱数表 Excelマクロ

    テニス等のダブルスゲームのペアを決めるための乱数表を作りたいと思い、Web検索したところrio_dさんが作成されたExcelマクロプログラムを見つけました(http://oshiete1.goo.ne.jp/kotaeru.php3?q=1388951)。記載されている通りにマクロを作成しましたが、実行すると「SubまたはFunctionが定義されていません」というコンパイルエラーメッセージが出てしまいます。rio_dさんのマクロプログラムの最初に「Sub 乱数表作成()」がありますが、この( )の中に何かを入力する必要があるのでしょうか。この他にも空白の( )がいくつかあります。マクロについて全くの素人で何も分かりません。このrio_dさんのマクロプログラムを実行する方法を素人にも分かるように解説していただければ幸いです。 【rio_dさんが書かれたマクロは以下の通りです】 <マクロ準備編> (1)新規ブックを開き、とりあえず名前をつけて保存します。『てにす乱数表.xls』にしましょうか。 (2)メニューバーから、ツール→マクロ→Visual Basic Editorを選択します。   Visual Basic Editorが起動します。 (3)左側に「VBAProject(てにす乱数表).xls」というのがあると思います。  ツリー状になっていて、左の[+]で展開していくと、「ThisWorkbook」という  ものが表示されると思います。 (4)その「ThisWorkbook」をダブルクリックします。  右側に「~~.xls - Thisworkbook(コード)」というウインドウが表示されます。 (5)そこに、下記のコードをコピー&ペーストしてください。 (6)Visual Basic Editorを閉じます。 (7)ここで一旦上書き保存しておきましょう。 <データ準備編> (1)セルA1に、コート数を入力してください。数字でお願いします。 (2)セルB1から横方向に、人数を入れていってください。 (3)セルA2から縦方向に、試合数を入れていってください。 こんなかんじ  _A__B_C_D__E__F__G__H__I__J__K 1|  3  5  6  7  8  9  10  11  12  13  14… 2|  1 3|  2 4|  3 5|  4 6|  5 7|  6    : <データ作成編> (1)メニューバーから、ツール→マクロ→マクロ と選択してください。 (2)実行するマクロの一覧に「ThisWorkbook.乱数表作成」というのがでるので、   それを選択して「実行」してください。 (3)砂時計が消えたら完成です。 このマクロは実行するたびに結果が変わります。気に入らなかったら何度でも やり直してください。 また、全セルを消去すれば、データ準備からやり直すことも出来ます。 好きな表をいくつでも作ってください。 ちなみに100人とかデータ数がえらく膨大になると、なかなか計算が終わりませんので。 その場合は気長に待ってください。 '-----マクロ ここから----- Sub 乱数表作成() Dim iRow As Integer Dim iCol As Integer Dim iCnt As Integer Dim iCnt2 As Integer Dim iTmp As Integer Dim sNum() As String Dim bChk() As Boolean Dim bChk2() As Boolean Dim bFull As Boolean Dim iCourt As Integer iCol = 2 Do Until Cells(1, iCol) = "" iRow = 2 If Cells(1, 1) * 4 > Cells(1, iCol) Then iCourt = Round(Cells(1, iCol) / 4 - 0.5, 0) Else iCourt = Cells(1, 1) End If ReDim sNum(iCourt * 4 - 1) ReDim bChk(Cells(1, iCol)) ReDim bChk2(Cells(1, iCol)) For iCnt = 1 To Cells(1, iCol) bChk(iCnt) = True bChk2(iCnt) = True Next iCnt Do Until Cells(iRow, 1) = "" iCnt = 0 Do Until iCnt = iCourt * 4 iTmp = Round(Rnd(Second(Now)) * Cells(1, iCol) + 0.5, 0) If bChk(iTmp) And bChk2(iTmp) Then sNum(iCnt) = "[" & Trim(Str(iTmp)) & "]" iCnt = iCnt + 1 bChk(iTmp) = False bChk2(iTmp) = False bFull = False For iCnt2 = 1 To Cells(1, iCol) bFull = bFull Or bChk(iCnt2) Next iCnt2 If bFull = False Then For iCnt2 = 1 To Cells(1, iCol) bChk(iCnt2) = True Next iCnt2 End If End If Loop Cells(iRow, iCol) = sNum(0) For iCnt = 1 To iCourt * 4 - 1 Select Case iCnt Mod 4 Case 0 Cells(iRow, iCol) = Cells(iRow, iCol) & Chr(10) & sNum(iCnt) Case 2 Cells(iRow, iCol) = Cells(iRow, iCol) & ":" & sNum(iCnt) Case Else Cells(iRow, iCol) = Cells(iRow, iCol) & sNum(iCnt) End Select Next iCnt For iCnt = 1 To Cells(1, iCol) bChk2(iCnt) = True Next iCnt iRow = iRow + 1 Loop iCol = iCol + 1 Loop End Sub '-----マクロ ここまで-----

  • 電卓作成(緊急です!!)

    電卓作成(緊急です!!) 以下のようなコードで電卓を作りました。これで完成かな?と思いきや1+2=7-8=29、1+2+3=5 となり不具合が出てしまいました。どう直せばこれを解決できますか?(=の所がおかしい?) Public Class Form電卓 Inherits System.Windows.Forms.Form Dim R1 As Integer 'レジスタの値 Dim R2 As Integer 'レジスタの保存 Dim Op As Integer '演算子 Dim CL As Integer '数字列の制御 windows フォームデザイナーで生成されたコード Private Sub Button終了_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button終了.Click End End Sub Private Sub 数字キー(ByVal k As Integer) If CL Then R1 = 0 CL = False End If R1 = R1 * 10 + k TextReg.Text = R1 End Sub Private Sub 演算キー(ByVal o As Integer) Op = o R2 = R1 CL = True End Sub Private Sub 計算() Select Case Op Case 1 R1 = R2 + R1 Case 2 R1 = R2 - R1 Case 3 R1 = R2 * R1 Case 4 R1 = R2 \ R1 End Select End Sub Private Sub KeyN0_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles KeyN0.Click 数字キー(0) End Sub ’(引数が1~9と置き換わったコードがこの下に続きますが長くなるので今は省略します) Private Sub KeyOA_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles KeyOA.Click 演算キー(1) End Sub ’(引数が2~4と置き換わったコードがこの下に続きますが長くなるので今は省略します) Private Sub KeyEg_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles KeyEg.Click 計算() TextReg.Text = R1 End Sub Private Sub KeyCl_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles KeyCl.Click R1 = 0 R2 = 0 Op = 0 CL = True TextReg.Text = "" End Sub Private Sub Form電卓_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load R1 = 0 R2 = 0 Op = 0 CL = True TextReg.Text = "" End Sub End Class

  • VB2005で、動的にコントロールを作成出来ない件

    MDIのフォームで、 子フォーム1にコントロール(ラベルなど)を追加したい場合、 子フォーム2のボタンクリックで追加しようとすると 追加されません。 (子フォーム1のボタンで同一フォームへコントロールを  追加しようとすると追加できました。) どのようにすれば追加できるでしょうか? 子フォーム2の追加ボタン関数のコード Private Sub Add_click()  AddLabel(子フォーム1, "hogehoge") End Sub モジュール(関数群)のコード Private Sub AddLabel(Byval objForm As Form, ByVal strText As String)  Dim ctlAddLabel As New Label()  With ctlAddLabel   .AutoSize = False   .Location = New Point(0, 0)   .Size = New Size(200, 40)   .Name = "Label" & Counter 'Counter は追加の度に1ずつ増えます   .Text = strText  End With  objForm.Controls.Add(ctrlAddLabel) End Sub

  • Form1 Load で実行されない。

    以前も同じ質問をしましたが、カテゴリーが不適当だったようですので、再度質問します。 よろしくお願いします。 VB2010のある参考書に下記のようなプログラムがありました。 Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim g As Graphics = Me.PictureBox1.CreateGraphics() g.DrawEllipse(Pens.Black, 0, 0, 100, 100) End Sub ボタンをクリックすると円が描けます。これをプログラムの起動時に実行させようと思い Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim g As Graphics = Me.PictureBox1.CreateGraphics() g.DrawEllipse(Pens.Black, 0, 0, 100, 100) End Sub と、しましたが実行されません。 どうすれば良いのでしょうか?

  • EXCEL2000とEXCEL2003のVBAについて

    現在、EXCEL2000で下記のコードを実行しています。 が、EXCEL2003で実行すると、 .UsedRange.Copy myb のコードが実行されているのにコピー出来ていません。 ファイルは開いていて、エラーは出ていないのです。 問題点わかる方教えていただけますか? Sub 日別データ読込() Dim rngsaki As Range Dim pathmacrobook As String Dim namebook As String Dim motobook As Workbook Dim myb As Variant Set rngsaki = Workbooks("残高集計用.xls").Worksheets(3).Range("a2") pathmacrobook = ThisWorkbook.Path & "\CSV読込データ12\" namebook = Dir(pathmacrobook & "*.xls") Do While Not namebook = "" Set motobook = Workbooks.Open(pathmacrobook & namebook) Set myb = Workbooks("残高集計用.xls").Worksheets(3).Range("A65536").End(xlUp) With motobook.Worksheets("Sheet1") .UsedRange.Copy myb End With motobook.Close False namebook = Dir() Loop MsgBox "完了しました" End Sub

  • 同じコマンドボタンからマウスカーソルがはなれたら

    フォーム上のコマンドボタンにマウスカーソルが触れたら色を付ける、 同じコマンドボタンからマウスカーソルがはなれたら 、また色を変える、 という動きをvbaで行いたいのですが、 Private Sub cmd_test_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Me.cmd_test.BackColor = RGB(255, 180, 200) End Sub で、マウスカーソルが触れたら色を付けることはできたのですが、 マウスカーソルがそのコマンドボタンから離れたら色を変えるという動きができません。 Private Sub cmd_test_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) Me.cmd_test.BackColor = RGB(255, 255, 255) End Sub Private Sub cmd_test_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) Me.cmd_test.BackColor = RGB(255, 255, 255) End Sub Private Sub cmd_test_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Me.cmd_test.BackColor = RGB(255, 255, 255) End Sub をしても、マウスカーソルが離れても色が白になりませんでした。

  • Buttonを押してもファンクションF1を押しても同じコードを実行したい

    VS.NETでの開発です。 初歩的な質問ですいません。 フォームにButton1を貼り付けて、以下でButton1がクリックされたときにコードが実行されますが、 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click End Sub ファンクションF1を押しても、同じコードが実行されるようにしたいのですが、 どのようにコードを記述すればよろしいでしょうか?

  • VB2008とExcel2003連携

    VB2008とExcel2003連携 VBでExcelの操作を、VBのボタン操作でOPEN処理、CEL操作、CLOSE処理をそれぞれ単独に処理したいのですが方法がわかりません。以下の記述では、OPEN処理後、CEL操作のため再度呼び出すと、前回呼び出したOPEN処理の内容が残っていません。VBAはある程度理解していますが、VBのCLASS等の概念が良く理解できていません。できれば、OPEN処理、CELの処理、CLOSE処理を別々のSUBにしたいので、その方法を優先して教えていただければ幸いです。 宜しくお願いします。 Public Class Form1 Public Sub xlsAccess(ByVal xlPrc As String) Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet Dim strFilename As String = "C:\TEST\SAMPLE.xls" 'ファイル名(フルパス)をセット Dim strSheetName As String = "Sheet1" 'シート名/シート名をセット ‘【EXCELファイルを開く】 If xlPrc = "OPEN" Then xlApp = CreateObject("Excel.Application") 'Application生成 xlApp.Workbooks.Open(Filename:=strFilename, UpdateLinks:=0) 'EXCELを開く xlApp.Visible = True 'EXCELの表示 xlBook = xlApp.Workbooks(Dir(strFilename)) 'Workbook xlSheet = xlBook.Worksheets(strSheetName) 'Worksheet xlSheet.Cells(1, 1).Value = "HELLO" End If '【EXCEL セル操作】 If xlPrc = "R/W" Then For k = 2 To 10 Step 1 xlSheet.Cells(k, 2).Value = xlSheet.Cells(1, 1).Value Next k End If ‘【EXCELファイル終了処理】 If xlPrc = "CLOSE" Then xlBook.Close(SaveChanges:=True) 'ブックを保存して終了 xlApp.Quit() 'EXCELを閉じる xlSheet = Nothing 'オブジェクトの解放 xlBook = Nothing 'オブジェクトの解放 xlApp = Nothing 'オブジェクトの解放 End If End Sub ‘【ボタン操作OPEN】 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click xlsAccess("OPEN") MsgBox("Open Excuted") End Sub ‘【ボタン操作、CEL操作】 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click xlsAccess("R/W") MsgBox("R/W Excuted") End Sub ‘【ボタン操作、CLOSE】 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click xlsAccess("CLOSE") MsgBox("CLOSE Excuted") End Sub End Class

専門家に質問してみよう