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

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

Related

Change the author of comments

I have a list of words in a table. I have a VBA word macro that reads this table. When the macro identifies the words in the table, it adds comments or suggestions. For example: "don't use that word". Currently the author of those comments is defaulted to the name of whoever runs the macro. If user John Wayne runs the macro, each comment is displayed with the label "John Wayne" as the author. How can I change the author to "robot"? I added the comment.author line but it doesn't work.
Do While .Execute(Forward:=True) = True
suggestion = Documents(DocName).Tables(1).Rows(RowCounter).Cells(CellWithSuggestion).range.Text
ActiveDocument.Comment.Author = "robot"
ActiveDocument.Comments.Add findRange, Text:=suggestion
findRange.Collapse wdCollapseEnd 'to avoid getting into endless loop
Loop 'do while
You have to set the author per created comment.
Use this sub for it
Option Explicit
Private Const SystemAuthorForComments As String = "robot"
Sub addComment(rgComment As Range, strMessage As String, _
Optional ByVal strAuthor As String)
If LenB(strAuthor) = 0 Then strAuthor = SystemAuthorForComments
Dim doc As Word.Document: Set doc = rgComment.Parent
Dim c As Word.Comment
Set c = doc.Comments.Add(rgComment, strMessage)
c.Author = strAuthor
End Sub
You would have to change your code snippet to:
Do While .Execute(Forward:=True) = True
suggestion = Documents(DocName).Tables(1).Rows(RowCounter).Cells(CellWithSuggestion).Range.Text
addComment findrange, suggestion '--> this is how you call the sub
findrange.Collapse wdCollapseEnd 'to avoid getting into endless loop
Loop 'do while
Workaround to change the author of comments to "robot":
Add "_0" at the end of all comment's author name.
Process to add new comments.
Change comments to author = "robot". Comments with an author that ends in "_0" stay intact.
Dim brand As String
Dim Comment As Comment
brand = "robot"
If ActiveDocument.Comments.Count > 0 Then
For Each Comment In ActiveDocument.Comments
Comment.Author = Comment.Author & "_0"
Next
End If
If ActiveDocument.Comments.Count > 0 Then
For Each Comment In ActiveDocument.Comments
If InStr(1, Comment.Author, "_0", 1) = 0 Then
Comment.Author = brand
End If
Next
End If

Catia VBA Automation Error Run-Time 80010005 - Selection ERROR

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

Validation: Allowing one specific word only once can be input in textbox in VBA Excel

I have a 4 different words (financial, location, course, professor) that can be inputted in a textbox, but each word must be used only once per input in the textbox.
For example, I enter a sentence in the textbox like this: "I have a problem with financial because my family is facing a financial problem" the code below processes this sentence into split text.
What I want to do for validation is to inform the user (maybe through msgbox) something like:
"Error - you must used financial only once in a sentence."
In addition, if course, location and professor used more than once in a sentence should also give a msgbox.
Private Sub CommandButton1_Click()
Call SplitText
End Sub
Sub SplitText()
Dim WArray As Variant
Dim TextString As String
TextString = TextBox1
WArray = Split(TextBox1, " ")
If (TextString = "") Then
MsgBox ("Error: Pls Enter your data")
Else
With Sheets("DatabaseStorage")
.Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(UBound(WArray) + IIf(LBound(WArray) = 0, 1, 0)) = Application.Transpose(WArray)
End With
MsgBox ("Successfully inserted")
End If
End Sub
Try this:
Private Sub CommandButton1_Click()
Call SplitText
End Sub
Sub SplitText()
Dim sentence As String
Dim mycount As Long
sentence = InputBox("Enter the sentence")
mycount = UBound(Split(sentence, "financial"))
If mycount > 1 then
Msgbox "Error - you must used financial only once in a sentence"
End if
'Here the rest of the code you need
End Sub
Hope it helps.

MS Access, DoEvents to exit loop

What I'd like to accomplish:
Do While ctr < List and Break = False
code that works here...
DoEvents
If KeyDown = vbKeyQ
Break = True
End If
loop
Break out of a loop by holding down a key (eg, Q). I've read up on DoEvents during the loop in order to achieve the functionality that I want. The idea is to have a Do While loop run until either the end of the list is reached or when Q is held down. I'm having issues getting the code to work the way I want, so I'm reaching out to hopefully end the frustration. My experience with VBA is very limited.
UPDATE - More code to expose where the problem might be. This is all in the order I have it (in case order of subs makes a difference:
Private Sub Form_KeyPress(KeyAscii As Integer)
Dim strChar As String
strChar = UCase(Chr(KeyAscii))
If strChar = "Q" Then
blnQuit = True
Debug.Print "Q pressed"
End If
End Sub
Private Sub Master_Report_Click()
Dim i As Integer
Dim Deptarray
blnQuit= False
If IsNull(Me.Hospital) Then
MsgBox ("Please Choose a Hospital")
Else
DoCmd.OpenForm "Report Print/Update", acNormal, , , , acDialog
If Report_choice = "Current_List" Then
Debug.Print "Create master rec report"
DoCmd.OpenReport "Master Rec Report", acViewPreview
DoCmd.RunCommand acCmdZoom100
ElseIf Report_choice = "Update_All" Then
total = (DCM_Dept.ListCount - 1)
ctr = 1
Do While ctr < (DCM_Dept.ListCount) And LoopBreak = False
Debug.Print "LoopBreak: "; LoopBreak
Debug.Print "Counter: "; ctr
DCM_Dept.Value = DCM_Dept.Column(0, ctr)
Update_Site (Me.Hospital)
ctr = ctr + 1
'DoEvents
' If vbKeyQ = True Then
'LoopBreak = True
'End If
Loop
Debug.Print "Update loop exited"
Debug.Print "Create master rec report"
DoCmd.OpenReport "Master Rec Report", acViewPreview
DoCmd.RunCommand acCmdZoom100
Else
End If
End If
End Sub
Private Sub Update_Site(Site As String)
If IsNull(Me.Hospital) Then
MsgBox ("Please Choose a Hospital")
ElseIf IsNull(Me.DCM_Dept) Then
MsgBox ("Please Choose a Department")
ElseIf Site = "FORES" Then
Debug.Print "Run FORES update macro"
DoCmd.RunMacro "0 FORES Master Add/Update"
ElseIf Site = "SSIUH" Then
Debug.Print "Run SSIUH update macro"
DoCmd.RunMacro "0 SSIUH Master Add/Update"
End If
End Sub
Report_choice and LoopBreak are both Public variables. My original idea was to have a popup form floating over the main form to display a counter ("Processing department X of Y") and a button to break the loop on there. I realized that the form was unresponsive while the Update_Site() was running its macro so I decided to go with holding a key down instead.
So, where do I go from here to get OnKeyDown to work? Or, is there a better way to do it?
Try to set the Key Preview of the form to Yes and add a variable blnQuit and a key press event in your form like this:
Private blnQuit As Boolean
'form
Private Sub Form_KeyPress(KeyAscii As Integer)
Dim strChar As String
strChar = UCase(Chr(KeyAscii))
If strChar = "Q" Then
blnQuit = True
End If
End Sub
Then check the blnQuit in your Do While condition, like this:
blnQuit = False
Do While ctr < List And Not blnQuit
code that works here...
DoEvents
loop

How do you remove hyperlinks from a Microsoft Word document?

I'm writing a VB Macro to do some processing of documents for my work.
The lines of text are searched and the bracketed text is put in a list(box).
The problem comes when I want to remove all hyperlinks in the document and then generate new ones (not necessarily in the location of the original hyperlinks)
So the problem is How do I remove the existing hyperlinks?
My current issue is that every time a link gets added, the hyperlinks count goes up one, but when you delete it, the count does NOT reduce. (as a result I now have a document with 32 links - all empty except for 3 I put in myself - they do not show up in the document)
At the end of the code are my attempts at removing the hyperlinks.
Private Sub FindLinksV3_Click()
ListOfLinks.Clear
ListOfLinks.AddItem Now
ListOfLinks.AddItem ("Test String 1")
ListOfLinks.AddItem ActiveDocument.FullName
SentenceCount = ActiveDocument.Sentences.Count
ListOfLinks.AddItem ("Sentence Count:" & SentenceCount)
counter = 0
For Each myobject In ActiveDocument.Sentences ' Iterate through each element.
ListOfLinks.AddItem myobject
counter = counter + 1
BracketStart = (InStr(1, myobject, "("))
If BracketStart > 0 Then
BracketStop = (InStr(1, myobject, ")"))
If BracketStop > 0 Then
ListOfLinks.AddItem Mid$(myobject, BracketStart + 1, BracketStop - BracketStart - 1)
ActiveDocument.Sentences(counter).Select
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _
"http://testnolink/" & counter, ScreenTip:="" 'TextToDisplay:=""
End If
End If
Next
'ActiveDocument.Sentences(1).Select
'
'Selection.Range.Hyperlinks(1).Delete
ActiveDocument.Hyperlinks.Item(1).Delete
Debug.Print ActiveDocument.Hyperlinks.Count
End Sub
This is an old post, so am adding this VBA code in case it is useful to someone.
Hyperlinks (Collections) need to be deleted in reverse order:
Sub RemoveHyperlinksInDoc()
' You need to delete collection members starting from the end going backwards
With ActiveDocument
For i = .Hyperlinks.Count To 1 Step -1
.Hyperlinks(i).Delete
Next
End With
End Sub
Sub RemoveHyperlinksInRange()
' You need to delete collection members starting from the end going backwards
With Selection.Range
For i = .Hyperlinks.Count To 1 Step -1
.Hyperlinks(i).Delete
Next
End With
End Sub
The line removing the hyperlink is commented out. The following line will remove the first hyperlink within the selected range:
Selection.Range.Hyperlinks(1).Delete
This will also decrement Selection.Range.Hyperlinks.Count by 1.
To see how the count of links is changing you can run the following method on a document:
Sub AddAndRemoveHyperlink()
Dim oRange As Range
Set oRange = ActiveDocument.Range
oRange.Collapse wdCollapseStart
oRange.MoveEnd wdCharacter
Debug.Print ActiveDocument.Range.Hyperlinks.Count
ActiveDocument.Hyperlinks.Add oRange, "http://www.example.com"
Debug.Print ActiveDocument.Range.Hyperlinks.Count
ActiveDocument.Hyperlinks.Item(1).Delete
Debug.Print ActiveDocument.Range.Hyperlinks.Count
End Sub