2016-07-03 2 views
1

VBA 생성 ActiveX 확인란을 클래스 모듈에 할당하는 데 문제가 있습니다. 사용자가 버튼을 클릭 할 때 달성하고자하는 목표는 다음과 같습니다. 첫째 - 엑셀 시트의 모든 체크 상자를 삭제합니다. 두번째 - 자동 체크 박스의 무리를 생성; 3rd - 클래스 모듈을이 새로운 체크 박스에 할당합니다. 그러면 사용자가 그 중 하나를 계속 클릭 할 때 클래스 모듈이 실행됩니다. 나는 이전 게시물 Make vba code work for all boxes에서 많이 차용 한VBA를 사용하여 클래스 모듈에 모든 확인란을 할당하십시오.

내가 가진 한 문제는이 첫 번째로 연속적으로 실행할 때 3 루틴 (새로운 체크 박스에 클래스 모듈을 할당 할) 작동하지 않는다는 것입니다 루틴. 확인란을 만든 후에 독립 실행 형으로 실행하면 정상적으로 실행됩니다. 내가 말할 수있는 최선의 방법은 VBA가 클래스 모듈을 할당 할 수 있도록 만들어진 후 체크 박스를 "해제"하지 않는 것입니다.

아래 코드는이 문제를 보여주는 간단한 코드입니다. 이 코드에서는 Sub RunMyCheckBoxes()를 실행하기 위해 "Sheet1"의 단추를 사용합니다. 버튼 1을 클릭하면 클래스 모듈이 새로 생성 된 체크 박스에 할당되지 않습니다. Sub RunAfter()를 실행하기 위해 "Sheet1"의 버튼 2를 사용합니다. 버튼 1을 클릭 한 후 버튼 2를 클릭하면 확인란이 클래스 모듈에 할당됩니다. 첫 번째 버튼을 클릭하면 클래스 모듈이 할당되지 않는 이유를 알 수 없습니다. 도와주세요.

Module1의 : 컬렉션

Sub RunMyCheckboxes() 
Dim i As Double 
Call DeleteAllCheckboxesOnSheet("Sheet1") 
For i = 1 To 10 
    Call InsertCheckBoxes("Sheet1", i, 1, "CB" & i & "1") 
    Call InsertCheckBoxes("Sheet1", i, 2, "CB" & i & "2") 
Next 
Call SetCBAction("Sheet1") 
End Sub 

Sub DeleteAllCheckboxesOnSheet(SheetName As String) 
Dim obj As OLEObject 
For Each obj In Sheets(SheetName).OLEObjects 
    If TypeOf obj.Object Is MSForms.CheckBox Then 
     obj.Delete 
    End If 
Next 
End Sub 

Sub InsertCheckBoxes(SheetName As String, CellRow As Double, CellColumn As Double, CBName As String) 
Dim CellLeft As Double 
Dim CellWidth As Double 
Dim CellTop As Double 
Dim CellHeight As Double 
Dim CellHCenter As Double 
Dim CellVCenter As Double 

CellLeft = Sheets(SheetName).Cells(CellRow, CellColumn).Left 
CellWidth = Sheets(SheetName).Cells(CellRow, CellColumn).Width 
CellTop = Sheets(SheetName).Cells(CellRow, CellColumn).Top 
CellHeight = Sheets(SheetName).Cells(CellRow, CellColumn).Height 
CellHCenter = CellLeft + CellWidth/2 
CellVCenter = CellTop + CellHeight/2 
With Sheets(SheetName).OLEObjects.Add(classtype:="Forms.CheckBox.1", Link:=False, DisplayAsIcon:=False, Left:=CellHCenter - 8, Top:=CellVCenter - 8, Width:=16, Height:=16) 
    .Name = CBName 
    .Object.Caption = "" 
    .Object.BackStyle = 0 
    .ShapeRange.Fill.Transparency = 1# 
End With 
End Sub 

Sub SetCBAction(SheetName) 
Dim cCBEvents As clsActiveXEvents 
Dim o As OLEObject 
Set mcolEvents = New Collection 
For Each o In Sheets(SheetName).OLEObjects 
    If TypeName(o.Object) = "CheckBox" Then 
     Set cCBEvents = New clsActiveXEvents 
     Set cCBEvents.mCheckBoxes = o.Object 
     mcolEvents.Add cCBEvents 
    End If 
Next 
End Sub 


Sub RunAfter() 
Call SetCBAction("Sheet1") 
End Sub 

클래스 모듈로 공공 mcolEvents (clsActiveXEvents) : 명시 옵션

Public WithEvents mCheckBoxes As MSForms.CheckBox 

Private Sub mCheckBoxes_click() 
MsgBox "test" 
End Sub 

UPDATE : 추가 연구에 는 바닥 대답에 게시 된 해결책이 여기에 : Creating events for checkbox at runtime Excel VBA

분명히 당신은 지금 시간에 실행하는 엑셀 VBA를 강제해야 Application.OnTime 이제 ""이 문제를 해결하기 위해 노력하고 코드의

편집 라인 :이 새로운 서식,

Sub RunMyCheckboxes() 
Dim i As Double 
Call DeleteAllCheckboxesOnSheet("Sheet1") 
For i = 1 To 10 
    Call InsertCheckBoxes("Sheet1", i, 1, "CB" & i & "1") 
    Call InsertCheckBoxes("Sheet1", i, 2, "CB" & i & "2") 
Next 
Application.OnTime Now, "SetCBAction" '''This is the line that changed 
End Sub 

을 그리고를 :

+0

다른 게시물에 해결책을 찾았 신속하고 아래의 예제는 당신에게 당신의 전체 작업을 체계화 할 수있는 방법의 아이디어를 줄 것이다 쉬운 일 후 당신이 경우

. 위의 원본 게시물을 솔루션으로 수정했습니다. 분명히 시간에 지금 VBA를 실행해야합니다 "Application.OnTime Now" – user6544548

+0

롤, 난 그냥 알아 냈어. 문제는 Ole Server가 VBA 외부에서 컨트롤을 만들고 있다는 것입니다. –

+0

은 나에게별로 의미가 없지만 전에 DoEvents를 시도해 보았습니다. Excel이 작업을 끝내도록하기 위해서였습니다. OLE 개체는 매우 느립니다. 'With Sheets (SheetName) .OLEObjects.Add (...) : Set cCBEvents.mCheckBoxes = .object' 등의 작업을 수행하는 대신 개체를 만드는 동안 컬렉션 및 클래스 이벤트를 설정할 수도 있습니다. –

답변

0

OLE 개체가 필요에 맞는 경우 솔루션을 찾았 기 때문에 기쁩니다.

Excel의 Checkbox 개체를 사용하면이 작업을 훨씬 간단하고 빠르게 처리 할 수 ​​있다는 것을 알고 있습니까? 단순함은 Checkboxes 컬렉션을 쉽게 반복 할 수 있으며 해당 .OnAction 속성에 액세스 할 수 있다는 사실에 있습니다. Evaluate 기능을 이용하여 '보낸 사람'을 쉽게 식별 할 수 있습니다. 모양을 맞춤화해야하는 경우 서식 기능이 있습니다.

Public Sub RunMe() 
    Const BOX_SIZE As Integer = 16 
    Dim ws As Worksheet 
    Dim cell As Range 
    Dim cbox As CheckBox 
    Dim i As Integer, j As Integer 
    Dim boxLeft As Double, boxTop As Double 

    Set ws = ThisWorkbook.Worksheets("Sheet1") 

    'Delete checkboxes 
    For Each cbox In ws.CheckBoxes 
     cbox.Delete 
    Next 

    'Add checkboxes 
    For i = 1 To 10 
     For j = 1 To 2 
      Set cell = ws.Cells(i, j) 
      With cell 
       boxLeft = .Width/2 - BOX_SIZE/2 + .Left 
       boxTop = .Height/2 - BOX_SIZE/2 + .Top 
      End With 
      Set cbox = ws.CheckBoxes.Add(boxLeft, boxTop, BOX_SIZE, BOX_SIZE) 
      With cbox 
       .Name = "CB" & i & j 
       .Caption = "" 
       .OnAction = "CheckBox_Clicked" 
      End With 
     Next 
    Next 
End Sub 
Sub CheckBox_Clicked() 
    Dim sender As CheckBox 

    Set sender = Evaluate(Application.Caller) 
    MsgBox sender.Name & " now " & IIf(sender.Value = 1, "Checked", "Unchecked") 
End Sub 
+0

Thanks Ambie. 내가 본 것에서 보면 ActiveX 컨트롤은 Forms 컨트롤보다 더 많은 인터페이스 옵션을 제공합니다. 이 필요성에 따라 ActiveX 경로를 선택했습니다. – user6544548

관련 문제