InsertCrossReference Fails On Last Item - vba

I think I have found a bug with the InsertCrossReference. If I use from code for the last list item in the document and there being nothing after that list item, it fails with error "Run-time error '4198' Command failed". If you do it manually, it all works. So you are thinking, I have written the code incorrectly, but this isn't the case. To make sure, i recorded a macro of inserting the cross reference and then ran the macro it recorded and the same error happens.
I have googled this problem and seen a couple of people raise it but a)they haven't pointed out that it only fails for the last list item and there being nothing in the document after that list item b)they haven't had any work-around replies.
I am using Word 2010 but I have also tried it on Word 2013 and the same thing happens.
If you want an example, if I set up the following:
This is my xref
Hello
Bye
where 1 and 2 are standard numbered lists and I have nothing in the document after "Bye" and then I run:
ActiveDocument.Range(16, 16).InsertCrossReference ReferenceType:="Numbered item", _
ReferenceKind:=wdNumberFullContext, ReferenceItem:="2", InsertAsHyperlink _
:=True, IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
Note having nothing after "Bye" is key. If you start a new line, with or without a list type, the code above will work
If anyone has any work-around for this, I'd appreciate it

You cannot insert anything AFTER the last paragraph mark in a document. I've had this issue in the past. My work around was to pragmatically add a paragraph mark in.
Something like the following:
Dim CRRange as Word.Range 'Make a range object to store where the cross reference will go.
set CRRange = ActiveDocument.Range(16,16)
if CRRange.end >= ActiveDocument.Range.End then 'Check to see if we reached the end of the document
ActiveDocument.Paragraphs.Add Range:=ActiveDocument.Range(ActiveDocument.Range.End -1, ActiveDocument.Range.End -1)
End If
CRRange.InsertCrossReference ReferenceType:="Numbered item", _
ReferenceKind:=wdNumberFullContext, ReferenceItem:="2", InsertAsHyperlink _
:=True, IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "

Related

'selection.footnotes.count' versus 'for each footnote in selection.footnotes'

I want to make some modification to the footnotes in a selected portion of a MS Word document. I would like to use a 'for each footnote in selection.footnotes', but this does not work. It returns all the footnotes in the document. I do not understand why, because if I run a 'selection.footnotes.count' this returns only the footnotes in the selected portion, which is what I want.
See this code, which can be used for testing the problem.
For example: type a number of lines in Word, insert some footnotes in each line, select one of the lines and run this code to see the difference.
Does anyone know what is wrong with my use of the For each footnote ...' statement?
For Each Footnote In Selection.Footnotes
i = i + 1
Next Footnote
MsgBox "• For ... Next: " & i & Chr(13) & _
"• Count: " & Selection.Footnotes.Count, vbOKOnly, "Number of footnotes in selection, counted using:"
I can reproduce what you describe, with the Range as well as the Selection object. I don't know "why"; it makes no sense as far as the object model goes. Sometimes, weird things happen with Selection, but that it also happens with Range...
I'd class it as a bug, but I don't have any confirmation to that effect from Microsoft.
This works, though
For ftCounter = 1 To rng.Footnotes.Count
Set ft = rng.Footnotes(ftCounter)
'Debug.Print ft.Range.Text
Next

Create macro to make text into hyperlink concatenating the display text to standard format

I have to create a large number of hyperlinks for ticket items where the only part of the URL that changes is the ticket ID. I am new to this and much of the VBA help is for excel. My problem exists in MS-word and its difficult to transfer the syntax.
I expect the user to invoke the macro after entering a 6 digit Ticket ID. Ideally the macro would automatically select the last word typed by the user, and append it to the url segment which never changes.
I attempted to record a macro that copies the last word typed then concatenates it onto the end of the standard URL.
I can successfully do everything with keyboard shortcuts so I thought I would be set. The problem is the macro just uses the text from the recording example. It also turns my text to display to the example text.
Turning any text into the link I used as an example in the recording.
I can't figure out how to make VBA use the copied text for the text to display and the last 6 digits of the URL.
Please see VBA syntax below
Sub textToHyperlink()
'
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
Selection.Copy
ChangeFileOpenDirectory _
"/Users/chris/Library/Containers/com.microsoft.Word/Data/Library/Preferences/AutoRecovery/"
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _
"https://someboringwebsite.com/WorkItem&id=123456", SubAddress:="", ScreenTip:="", _
TextToDisplay:="123456"
End Sub
This may work:
Sub textToHyperlink()
'
Dim TicketID As String
TicketID = Selection.Range.Text
'You may need to clean up TicketID (remove <CR> etc.) before
'sticking it in the hyperlink. Depends on what's in Selection.
' Not sure what this line does
' ChangeFileOpenDirectory _
"/Users/chris/Library/Containers/com.microsoft.Word/Data/Library/Preferences/AutoRecovery/"
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _
"https://someboringwebsite.com/WorkItem&id=" & TicketID, SubAddress:="", ScreenTip:="", _
TextToDisplay:=TicketID
End Sub
Hope that helps.
The following is in response to your clarification in a comment (which I've incorporated into your question). There are two variations
1) Following your premise, working with user input. Note that this will take the preceding word, no matter where it is in the text. And in the case the user may have typed a space (or many spaces) all spaces are removed from the end of that word. (These lines of code are commented out.)
2) You (and the user) might find it simpler to work with an InputBox so that the user can type the ticket id directly - no worries about where it is in the text, or spaces, or anything. The hyperlink is inserted at the selection.
Sub textToHyperlink()
'
Dim sID As String
' Dim rng As word.Range
'
' Set rng = Selection.Range
' rng.MoveStart wdWord, -1
' sID = Trim(rng.Text)
sID = InputBox("Please enter the ticket ID")
ActiveDocument.Hyperlinks.Add anchor:=rng, Address:= _
"https://someboringwebsite.com/WorkItem&id=" & sID, SubAddress:="", ScreenTip:="", _
TextToDisplay:=sID
End Sub

Automation Error - The Object Invoked has Disconnected from It Clients during autofilter

Ok, I know there are many posts about this but so far none of them have a solution that seems to work for me.
I ran across this for the first time a week ago and have created a very simple program to try and figure out what is going on. I have resorted to hand typing all this (I usually start with an old macro and modify it or copy and past code pieces); I have made my own data file just in case there was something weird with the file I am planning to use as the input; and it still errors out.
I have other macros that are doing the exact same processes and they still work fine. This is driving me insane. The code below crashes on the Autofilter line.
Sub Fred()
Dim strFileToOpen As String
Dim wbHL7 As Workbook
strFileToOpen = Application.GetOpenFilename(Title:="Please select the Invoice file.", FileFilter:="Excel Files *.xls* (*.xls*),")
If strFileToOpen = "False" Then
MsgBox "No file selected.", vbExclamation, "Sorry!"
Exit Sub
Else
Set wbHL7 = Workbooks.Open(Filename:=strFileToOpen)
End If
rCnt = Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Range("A1:K" & rCnt).AutoFilter Field:=11, Criteria1:=0, Operator:=xlFilterValues
ActiveSheet.Range("A1:K" & rCnt).Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
ActiveSheet.AutoFilterMode = False
End Sub
Many of the other posts hint that there might be an issue with my actual system such as compatibility things, but then why are the other macros still working? By the way, once it does this, it basically locks up everything to do with Excel and I have to open the Task Manager to kill the process. I am using Windows 7 and Office 2013.
Edit:
I just want to add that if I record an autofilter macro in the same book as the data, it works fine.
You have an error in your code. The criteria needs to be a string. If you look carefully at the recorded macro you'll see that it too uses a string.
Change your autofilter line to the following and it should work:
ActiveSheet.Range("A1:K" & rCnt).AutoFilter Field:=11, Criteria1:="=0", Operator:=xlFilterValues

Excel VBA Self-Destruct Switch

I have had my first "Client-took-my-work-and-then-ghosted-me-without-paying" experience. For the future, I want to put in a killswitch, disguised as a regular macro, which makes the whole thing unusable. That way, even if they hire someone to crack the password and remove my "Your trial has expired..." check, a normal-looking macro (Something like "Fix_Sheet_Formatting") would be easily overlooked and run, destroying everything and saving the changes.
However, that leaves the VBA... We're talking a full purge here, so everything must go. I'll figure out how to do all of this on my own, I just don't want to waste time pursuing something that isn't possible:
Can VBA code delete itself from a workbook while running or does it have to be deleted from a macro on another workbook? And would deleting the code cause the macro to stop running, or can I have it delete everything except a nasty MsgBox after everything is done?
I'll leave the comments to debating whether or not this is a good idea (IMHO it probably isn't). As to the question itself, of course it's possible, and won't interrupt macro execution:
Public Sub Example()
Dim proj As Object
Set proj = ThisWorkbook.VBProject
Dim comp As Object
For Each comp In proj.VBComponents
With comp.CodeModule
.DeleteLines 1, .CountOfLines
If comp.Name = "ThisWorkbook" Then
.InsertLines 1, "Private Sub Workbook_Open()" & vbCrLf & _
vbTab & "MsgBox ""Where's my money, ##$%&!?""" & vbCrLf & _
"End Sub"
End If
End With
Next
ThisWorkbook.Save
End Sub
Obfuscation is an exercise for the reader.
Put a loop with due date as your payment data . Inside write code to get macro into infinity loop or to delete code.
If payment happens on time then just comment above piece of code or else just wait client come back to you on next day defined in loop.

Editing Macro in VBA AutoFilter Array error

I'm editing a document with 2500 entries and need to apply an AutoFilter, and this is my first try at editing the macro code, please have patience.
I used record to create the macro, and when I went to edit parts of it I got "Compile error: Expected: expression" outside the portion of the code I edited. the '...' is many more entries.
ActiveSheet.Range("$A$1:$C$2500").AutoFilter Field := 2, Criteria1 := Array( _
"#N/A","3K Technologies, LLC","ABN","Accenture","AIMCo",...,"ITAT Partners" _
,"IT-Beratung Gunnar Hofmann","John Hancock","John Hancock Financial Network", _
End Sub
Not all the entries are shown and all of the code above except "End Sub" is in red.
It seems that since I recorded the macro, as opposed to writing it, all the name values are being stored and causing a problem. How do I apply an auto filter to a large selection of cells in VBA? Are the existing company names causing an overflow?
Thank you in advance!
If you just want to APPLY an Autofilter you can just use:
ActiveSheet.Range("$A$1:$C$2500").AutoFilter
All of the rest of your code is all of the settings you recorded like each check-box for each column.
If you're trying to edit the default selection settings in that stuff after the filter is applied, which section are you having trouble with in particular?
One thing to note is that Excel's VBA can only continue the same line of code down around 24 times with the _ symbol at the end. Excel will fail to record the filter's checkbox selections if there are too many so you'll have to code them in by hand if this is, in fact, the specific problem you are having then follow this setup:
With ActiveSheet.Range("$A$1:$C$2500")
'- Use only one line break with a long list off to the right of what you want selected
'- it may look ugly in code, but with Excel's limit of 24 lines it's necissary in this case.
.AutoFilter Field:=2, _
Criteria1:=Array("#N/A", "3K Technologies, LLC", "ABN", "Accenture", "AIMCo", "ITAT Partners", "IT-Beratung Gunnar Hofmann", "John Hancock", "John Hancock Financial Network")
'- Here you can add settings for additional columns like this:
'.AutoFilter Field:=1, _
' Criteria1:=Array("#N/A", "3K Technologies, LLC", "ABN", "Accenture", "AIMCo", "ITAT Partners", "IT-Beratung Gunnar Hofmann", "John Hancock", "John Hancock Financial Network")
End With