Catia VBA Automation Error Run-Time 80010005 - Selection ERROR - vba

I have a Problem with my Userform. It should automatically Switch to another TextBox when an selection in the catpart made. I get the Automation Error: It is illegal to call out while inside message filter.
Run-time error '-2147418107 (80010005)
Sub Auswahl_Click()
Dim sel As Object, Objekt As Object, ObjektTyp(0)
Dim b, Auswahl, i As Integer
ObjektTyp(0) = "Body"
Set sel = CATIA.ActiveDocument.Selection
For i = 1 To 6
sel.Clear
UserFormNow.Controls("Textbox" & i).SetFocus
Auswahl = sel.SelectElement2(ObjektTyp, "Wähle ein Body aus...", False)
Set b = CATIA.ActiveDocument.Selection.Item(i)
If Auswahl = "Normal" Then
Set Objekt = sel.Item(i)
UserFormNow.ActiveControl = Objekt.Value.Name
sel.Clear
End If
i = i + 1
Next
sel.Clear
End Sub
' EXCEL DATEI ÖFFNEN____________________________________
Sub Durchsuchen1_Click()
Dim FPath As String
FPath = CATIA.FileSelectionBox("Select the Excel file you wish to put the value in", "*.xlsx", CatFileSelectionModeOpen)
If FPath = "" Then
Else
DurchsuchenFeld.AddItem FPath
ListBox1.Clear
ListBox1.AddItem "Bitte wählen Sie das Panel"
TextBox1.SetFocus
End If
End Sub
' FORMULAR SCHLIEßEN____________________________________
Sub ButtonEnd_Click()
ButtonEnd = True
Unload UserFormNow
End Sub

First you have to know that when you use an UI and still want to interact with CATIA, you have to choices:
Launch the UI in NoModal: mode UserFormNow.Show 0
Hide the UI each time you want to interact with CATIA: Me.Hide or UserFormNow.Hide
Then, I strongly recommend you to avoid looking for items with names:
UserFormNow.Controls("Textbox" & i).SetFocus
If you want to group controls and loop through them, use a Frame and then use a For Each loop.
For Each currentTextBox In MyFrame.Controls
MsgBox currentTextBox.Text
Next
Regarding your code, many simplifications can be done:
Private Sub Auswahl_Click()
Dim sel As Object
Dim currentTextBox As TextBox
Dim Filter As Variant
ReDim Filter(0)
Filter(0) = "Body"
Set sel = CATIA.ActiveDocument.Selection
'Loop through each textbox
For Each currentTextBox In MyFrame.Controls
sel.Clear
'Ask for the selection and test the result at the same time
If sel.SelectElement2(Filter, "Wahle ein Body aus...", False) = "Normal" Then
'Get the name without saving the object
currentTextBox.Text = sel.Item2(1).Value.Name
Else
'allow the user to exit all the process if press Escape
Exit Sub
End If
Next
sel.Clear
End Sub

Related

Get the selected item of a dropdown in a custom menu (and run a macro accordingly)

I have this simple menu setup and I am trying to run a macro based on user selection of the label item from a dropdown list. The OnAction only works on the entire dropdown object and not executing macros per dropdown-list-item selection:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Dim oMenu As CommandBar
Set oMenu = CommandBars.Add("", msoBarPopup, , True)
Dim cbcm1 As CommandBarButton
Set cbcm1 = oMenu.Controls.Add(Type:=msoControlButton, Temporary:=True)
cbcm1.Caption = "Add new label"
cbcm1.OnAction = "AddNewLabel"
Dim cbcm2 As CommandBarComboBox
Set cbcm2 = oMenu.Controls.Add(Type:=msoControlDropdown, Temporary:=True)
cbcm2.Caption = "Select label:"
cbcm2.AddItem "NVPE" ' << this should run a macro that adds a 'NVPE' in some other range..
cbcm2.AddItem "COMP" ' << this should run a macro that adds a 'COMP' in some other range.. and so on.
cbcm2.AddItem "HOLD"
cbcm2.AddItem "INPROG"
cbcm2.AddItem "CANC"
cbcm2.Width = 150
cbcm2.ListIndex = 1 'default
cbcm2.OnAction = "NewCommand_OnAction"
cbcm2.Style = msoComboLabel
oMenu.ShowPopup 'display the menu
Cancel = True
End Sub
Any suggestions?
I can't think of a way to get the selected index or value (caption) of the selected item.
Thanks!
All you are missing is a Select Case in your event handler. Using your existing code, simply add the string cbcm2Text and set it to equal cbcm2.Text. Then, add the necessary Select Case prior to your Cancel = True statement to call your macros.
Example:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Dim oMenu As CommandBar
Dim cbcm2Text As String
Dim cbcm1 As CommandBarButton
Dim cbcm2 As CommandBarComboBox
Set oMenu = CommandBars.Add("", msoBarPopup, , True)
Set cbcm1 = oMenu.Controls.Add(Type:=msoControlButton, Temporary:=True)
Set cbcm2 = oMenu.Controls.Add(Type:=msoControlDropdown, Temporary:=True)
cbcm1.Caption = "Add new label"
cbcm1.OnAction = "AddNewLabel"
cbcm2.Caption = "Select label:"
cbcm2.AddItem "NVPE"
cbcm2.AddItem "COMP"
cbcm2.AddItem "HOLD"
cbcm2.AddItem "INPROG"
cbcm2.AddItem "CANC"
cbcm2.Width = 150
cbcm2.ListIndex = 1
cbcm2.OnAction = "NewCommand_OnAction"
cbcm2.Style = msoComboLabel
oMenu.ShowPopup
cbcm2Text = cbcm2.Text
Select Case cbcm2Text
Case "NVPE"
Call NVPE
Case "COMP"
Call COMP
Case "HOLD"
Call HOLD
Case "INPROG"
Call INPROG
Case "CANC"
Call CANC
End Select
Cancel = True
End Sub
Sub NVPE()
MsgBox "You selected NVPE"
End Sub
Sub COMP()
MsgBox "You selected COMP"
End Sub
Sub HOLD()
MsgBox "You selected HOLD"
End Sub
Sub INPROG()
MsgBox "You selected INPROG"
End Sub
Sub CANC()
MsgBox "You selected CANC"
End Sub
The preceding code produces the following result:
Here is the relevant Microsoft Documentation if you would like to see more examples of how to utilize combobox change events.

VBA WORD 2019 Redesigned comments. Looking for an Event like "Comment was added" or "Comment has changed" to autocorrect comment text afterwards

In 2019 comments in Word were redesigned. Therefore there was no autocorrection available in comments anymore.
I used the autocorrection function for substituting my own abbreviations in the comments.
I now wrote a VBA SUB making use of the Comments/Comment object and the AutoCorrect object.
It works fine to substitute my abbreviations in all comments after I wrote them. But to get a more immediate experience, I would like to link the SUB to a "Comment was added"- or "Comment has changed"-Event but I can't find one.
The closest I can get is via a call of my SUB in App_WindowSelectionChange() but the selection of a comment balloon or adding a new comment is not firing that event.
It should work like this:
editing autocorrection fu1 = fuggel1
Select: Word->Developement tools->macros-> Register_Event_Handler()
write comment including "fu1 is the best"
on event changing to "fuggel1 is the best"
Any ideas how to make the call of my SUB related to adding a new comment or changing a comment ?
Rem Class EventACC
Public WithEvents App As Word.Application
Private Sub App_WindowSelectionChange(ByVal Sel As Selection)
Rem Debug.Print ("change")
Call Auto_Correct_Comment
End Sub
Rem Module AutoCorrectComment
Dim ACC As New EventACC
Sub Register_Event_Handler()
Set ACC.App = Word.Application
End Sub
Sub Auto_Correct_Comment()
If ActiveDocument.Comments.Count >= 1 Then
For X = 1 To ActiveDocument.Comments.Count
Dim m_s_comment As String
Dim m_s_arr_comment_p() As String
m_s_comment = Trim(ActiveDocument.Comments(X).Range.Text)
m_s_arr_comment_p = Split(m_s_comment, " ")
For C = 0 To UBound(m_s_arr_comment_p)
Rem Debug.Print (m_s_arr_comment_p(C))
On Error Resume Next
Dim m_s_test As String
m_s_test = AutoCorrect.Entries(m_s_arr_comment_p(C)).Value
If Err.Number = 0 Then
Rem Debug.Print (AutoCorrect.Entries(m_s_arr_comment_p(C)).Value)
m_s_comment = Replace(m_s_comment, m_s_arr_comment_p(C), AutoCorrect.Entries(m_s_arr_comment_p(C)).Value)
Rem Debug.Print (m_s_comment)
End If
Next C
ActiveDocument.Comments(X).Range.Text = m_s_comment
Next X
End If
End Sub
I made some progess, now being able to change abbreviations in the selected comment via a key-shortcut (ALT + 0) after writing and confirming it or choosing the comment balloon later on. See code below. Still wanting an event related change.
Usage->Select: Word->Developement tools->macros->AddKeyBinding().
Then use the Key-Shortcut (Alt+0) on comments after writing and confirming them.
Rem Module AutoCorrectComment
Sub Auto_Correct_Comment_2()
If ActiveDocument.ActiveWindow.ActivePane.Selection.Comments.Count >= 1 Then
m_s_comment = Trim(ActiveDocument.ActiveWindow.ActivePane.Selection.Comments.Item(1).Range.Text)
m_s_comment_copy = m_s_comment
Replacement = Array(".", ",", "?", "!", ":") ' add more
For Each A In Replacement
m_s_comment_copy = Replace(m_s_comment_copy, A, " " & A & " ") ' necessary to "free" Autocorrect Element
Next A
m_s_arr_comment_p = Split(m_s_comment_copy, " ")
For C = 0 To UBound(m_s_arr_comment_p)
Rem Debug.Print (m_s_arr_comment_p(C))
On Error Resume Next
Dim m_s_test As String
m_s_test = AutoCorrect.Entries(m_s_arr_comment_p(C)).Value
If Err.Number = 0 Then
Debug.Print (m_s_arr_comment_p(C))
Rem Debug.Print (AutoCorrect.Entries(m_s_arr_comment_p(C)).Value)
m_s_comment = Replace(m_s_comment, m_s_arr_comment_p(C), AutoCorrect.Entries(m_s_arr_comment_p(C)).Value)
Rem Debug.Print (m_s_comment)
End If
Next C
ActiveDocument.ActiveWindow.ActivePane.Selection.Comments.Item(1).Range.Text = m_s_comment
End If
End Sub
Sub AddKeyBinding()
With Application
.CustomizationContext = ActiveDocument.AttachedTemplate
' \\ Add keybinding to Active.Document Shorcut: Alt+0
.KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyAlt, wdKey0), _
KeyCategory:=wdKeyCategoryCommand, _
Command:="Auto_Correct_Comment_2"
End With
End Sub

Copying cell value to textbox vba

I have been trying to write a macro that will dynamically fill a textbox on a new sheet will the value of a cell from another sheet.
I have managed to get it working using this:
Sub copyDetail()
' Define variables
Dim pre As Worksheet
Dim des As Worksheet
Set pre = Sheets("Presentation")
Set des = Sheets("Description")
Dim i As Integer
Dim lbl As String
' Scroll through labels and copy where boolean = 1
For i = 2 To 17
If des.Cells(i, 2) = 1 Then
lbl = des.Cells(i, 11)
Sheets("Presentation").Select
ActiveSheet.Shapes.Range(Array("TextBox 1")).Select
Selection.Text = lbl
Else
End If
Next i
End Sub
I basically want to be able to do exactly what this does but without using select all the time as this changes sheets and slows down my code (I have many other sub's to run alongside this one). I've tried things like defining the textbox using this:
Dim myLabel As Object
Set myLabel = pre.Shapes.Range(Array("TextBox 1"))
But then I get an "object doesn't support this property or method" error when I try and call:
myLabel.Text = lbl
You can set the text of a TextBox like so:
ActiveSheet.Shapes("TextBox 1").TextFrame.Characters.Text = "Hello world"
You can set-up a little helper Sub in a Module to make the code re-usable:
Public Sub SetTextBoxText(ws As Worksheet, strShapeName As String, strText As String)
Dim shp As Shape
On Error Resume Next
Set shp = ws.Shapes(strShapeName)
If Not shp Is Nothing Then
shp.TextFrame.Characters.Text = strText
Else
Debug.Print "Shape not found"
End If
End Sub

Run subprocedure under button -

I have this sub/macro that works if I run it as BeforeRightClick. However, I would like to change it so I can actually use my rightclick and put the macro on a button instead.
So I have tried to change the name from BeforeRightClick.
I have tried with both a normal form button and an ActiveX.
All this + some more code is posted under Sheet1 and not modules
Dim tabA As Variant, tabM As Variant
Dim adrA As String, adrM As String
' Set columns (MDS tabel) where data should be copied to (APFtabel)
'Post to
'P1-6 divisions ' Name adress, etc
Const APFtabel = "P1;P2;P3;P4;P5;P6;E9;E10;E13;E14;E23;N9;N10;N11;N12;N20"
'Load data from
Const MDStabel = "N;O;P;Q;R;S;H;Y;Z;AB;W;AF;T;D;AA;V;"
Dim APF As Workbook
' APFilNavn is the name of the AP form
Const APFilNavn = "APForm_macro_pdf - test.xlsm"
' Const APFsti As String = ActiveWorkbook.Path
Const APFarkNavn = "Disposition of new supplier"
' APsti is the path of the folder
Dim sysXls As Object, APFSti As String
Dim ræk As Integer
Private Sub CommandButton1_Click()
APFormRun
End Sub
' Here I changed it from BeforeRightClick
Private Sub APFormRun(ByVal Target As Range, Cancel As Boolean)
Dim cc As Object
If Target.Column = 8 Then
APFSti = ActiveWorkbook.Path & "\"
If Target.Address <> "" Then
For Each cc In Selection.Rows
Cancel = True
ræk = cc.Row
Set sysXls = ActiveWorkbook
åbnAPF
overførData
opretFiler
APF.Save
APF.Close
Set APF = Nothing
Set sysXls = Nothing
Next cc
End If
End If
End Sub
Private Sub overførData()
Dim ix As Integer
tabA = Split(APFtabel, ";")
tabM = Split(MDStabel, ";")
Application.ScreenUpdating = False
For ix = 0 To UBound(tabM) - 1
If Trim(tabM(ix)) <> "" Then
adrM = tabM(ix) & ræk
If tabA(ix) <> "" Then
adrA = tabA(ix)
End If
With APF.ActiveSheet
.Range(adrA).Value = sysXls.Sheets(1).Range(adrM).Value
End With
End If
Next ix
End Sub
Private Sub opretFiler()
' Here I run some other macro exporting the files to Excel and PDF
btnExcel
btnExportPDF
End Sub
if you put this code in Sheet1, then to access it from a button you need to define its name (in the button) as Sheet1.APFormRun (and I think you need to make it Public).
If you move the sub and everything it calls to a Module (after doing an Insert->Module), then you do not need the Excel Object Name prefix.
A very detailed write-up about scoping is at the link below. Scroll down to the "Placement of Macros/ Sub procedures in appropriate Modules" section: http://www.globaliconnect.com/excel/index.php?option=com_content&view=article&id=162:excel-vba-calling-sub-procedures-a-functions-placement-in-modules&catid=79&Itemid=475
In your code above, I had to comment out all the subs you didn't include just to get it to compile for debugging.
To make a sub accessible to the Macros button or to "Assign Macro..." you have to make it Public
Also to make a sub accessible, it cannot have any passed parameters.
So you will have to remove the passed parameters from the Public Sub APFormRun() definition
Therefore you will have to re-write the initial portion of APFormRun ... currently your APFormRun relies upon getting a passed parameter (Target) of the selected cell that you right-clicked upon. When you press a button, there is no cell that you are right-clicking upon. It is not a cell-identifying Excel event. You will have to obtain the selected cell via the Selection excel object. There are a lot of StackOverflow answers on how to do that.

Looping through a collection of text boxes

I have a userform that has three conceptual groups of textboxes. I'm trying to create a collection for each group and then when the user clicks on a button to call a sub/function associated with one of those groups, I want to be able to call a function that loops through the collection of textboxes associated with that group and check if they are empty, contain invalid characters, etc.
I've made the following declarations at the module level.
Dim typSectFields, laneFields, matFields As Collection
Then when the user form initializes I add the text boxes to the collections:
Set typSectFields = New Collection
With frmAddTypSect
typSectFields.Add txtTypSectName
typSectFields.Add txtStartSta
typSectFields.Add txtEndSta
End With
And then when the user clicks the button that uses the input from the "typSectFields" collection:
Dim tb As Control, res As VbMsgBoxResult
For Each tb In typSectFields
If tb.Text = vbNullString And t.Tag <> vbNullString Then
res = MsgBox("You've not completed the " + tb.Tag + " field. Would you like to complete it now?", vbYesNo + vbQuestion)
If res = vbYes Then Exit Sub
End If
Next
I get an "Object Required" error when execution hits the For loop.
VBE shows that tb = nothing and typSectFields = Empty.
What am I doing wrong?
Make sure all of your code (specifically the module-level declarations) are in the code behind the form module. The following runs without error for me:
Dim typSectFields As Collection, laneFields As Collection, matFields As Collection
Private Sub CommandButton1_Click()
Dim tb As Control, res As VbMsgBoxResult
For Each tb In typSectFields
If tb.Text = vbNullString And tb.Tag <> vbNullString Then
res = MsgBox("You've not completed the " + tb.Tag + " field. Would you like to complete it now?", vbYesNo + vbQuestion)
If res = vbYes Then Exit Sub
End If
Next
End Sub
Private Sub UserForm_Initialize()
Set typSectFields = New Collection
With frmAddTypSect
typSectFields.Add txtTypSectName
typSectFields.Add txtStartSta
typSectFields.Add txtEndSta
End With
End Sub