I'm using excel vba to extract information from a word document.
In the word document, there are levels of numbered lists. For example:
1. ABC
1.1 DEF
1.1.1 ABCDEF
2. AAA
2.1 BBB
2.1.1. CCC
and I need to get the full context of each heading in each level and put them into an excel range, i.e. {"1.ABC", "1.1 DEF", "1.1.1 ABCDEF", "2. AAA", "2.1 BBB", "2.1.1. CCC"}
The function I use is:
For Each sec In objDoc.getcrossreferenceitems(wdRefTypeNumberedItem)
However, my headings are truncated if the headings are too long. For example, I have (random text is added for confidentiality reasons):
"5.2.11. Current References: As part of the evaluation process, XXX will conduct 2340AERTQ3493YR. When selecting ADT34534FDGSR, please ensure that they are AERA34AEFDS."
But only
5.2.11. Current References: As part of the evaluation process, XXX will conduct 234
is displayed, and the rest of the sentence is gone.
If anybody has an alternate solution, please let me know.
i confirm this behavior. A workeable albeit and elaborate solution is to scan the document for all numbered items which gives you the full text and then cross reference that result against the list returned by the GetCrossReferenceItems. There's quite some work involved but works and gives you the ability to create one list with referable Headings and NumberedItems, which is what I did to build a more user friendly alternative to Word's own implementation.
You'll have to match the formatting Word applies to the list returned by GetCrossReferenceItems, ie. the identation and removal of special characters.
Be careful with track changes. There is a bug in GetCrossReferenceItems which means that items (in my case headers) that have a tracked change at the beginning of the text are not returned by GetCrossReferenceItems but internally are still on the list so the index is offset. If the item in question is item 11, then GetCrossReferenceItems gives the item belonging to item 12 the item 11. A workaround is to accept all revisions before GetCrossReferenceItems and undo it after.
It's not easy but works.
I met a similar problem in MSWord. I found some paragraph's text are shorten in the following code
Sub bug()
items = ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem)
For idx = 1 To UBound(items)
MsgBox items(idx)
Next
End Sub
I have to use a some long solution( in Python, sorry. But is is easy to rewrite in VBA):
varHeadings = []
for par in objDoc.Paragraph:
if par.Range.ListFormat.ListType == win32com.client.constants.wdListOutlineNumbering:
idx = par.Range.ListFormat.ListString
txt = par.Range.Text.strip('\n').strip('\r')
varHeadings.append('%s%s' % (idx, par.Range.Text))
which does work. However, as I have said, it is some tedious. So did I miss some VBA function in MSWord, or GetCrossReferenceItems has known bug and can not found any replacement in VBA?
Related
How can I change the Heading Number with VBA code?
For example, "1.1 Computer system"
I'd like to change "1.1" to "1.2".
I can read it with:
Selection.Paragraphs(1).Range.ListFormat.ListString
I can't find a way to change it.
Basic Function Test
1.1. LED Function Test Purpose: To make sure all the LED Functions are working as the Product Specification Resource Requirements:
The context is shown above. Sometimes, I copy from another document. The pasted heading number is not correct.
I tried to record the macro but the recorded macro is empty.
To force Heading 2 to start the numbering from 1.2, all you need is:
ActiveDocument.Styles(wdStyleHeading2).ListTemplate.ListLevels(2).StartAt = 2
Your update shows you're trying to do something quite different, however.
The only reliable way to retain the original numbering when copying/pasting between documents is to either:
convert the source numbering to static text before copying; or
paste the copied content as unformatted text.
I am new to libreoffice basic, i have experience with VBA but this libreoffice is different.
I just want to get cell value but it always return zero value to me while the actuall cell can be text or number.
Here is a partial of my simple code.
Sub test_moved()
Dim Doc As Object
'worksheet
Dim sh_village As Object
Dim sh_cbc As Object
sh_village = ThisComponent.CurrentController.getActiveSheet()
'sh_village = Doc.Sheets.getByName("VillageFinal")
'sh_village = Doc.Sheets(1)
Msgbox(sh_village.getCellrangeByName("B2").getValue())
Msgbox(sh_village.getCellrangeByName("B2").Value)
Msgbox(sh_village.getCellByPosition(1,1).Value)
msgbox("The process is completed.")
End Sub
Do we need to do prior task before start coding?
The code works correctly for numeric values. However, for strings, including strings that look like a number, it will display 0 because there is no numeric value.
What you probably want instead is:
MsgBox(sh_village.getCellRangeByName("B2").getString())
Also check out Format -> Cells -> Number to see how the data is displayed in the cell. And be on the lookout for a single quote at the front of the value in the formula bar (for example '42), because that means it is a string. Delete the quote to make it a number.
i have experience with VBA but this libreoffice is different.
Yes, LibreOffice Basic is a different language from VBA and the LibreOffice API is very different from the MS Office API. Knowing that will help you use it more effectively. If possible, avoid Option Compatible, because it won't fix most problems and will only muddy the waters.
I'm using below line to get a selected drop down from an endoresment.
ActiveDocument.FormFields(ActiveDocument.Range.Bookmarks(Selection.Information(30)).Name).Dropdown.Value
But I'm unable to get the correct bookmark index through Selection.Information(30) hence getting incorrect bookmark name.
Can any one please help me here.
The more "conventional" way to get the name of the currently active/selected bookmark name is:
Selection.Bookmarks(1).Name
Since this appears to be a form field, it's also possible to get the name via that collection:
Selection.Range.FormFields(1).Name
In a comment the request is for the bookmark index, although the request in the Question is for the bookmark name... In any case, to get the bookmark index get the count of all bookmarks from the start of the document to the end of the selection. (Note that this gets the index of the last previous bookmark, which is not necessary in the selection):
bkmIndex = ActiveDocument.Range(0, Selection.Range.End).Bookmarks.Count
Debug.Print ActiveDocument.Bookmarks(bkmIndex).Name
Please note that Information(30) is an old Word Basic value (I had to look it up in 1995 literature) that has no official equivalent in the VBA object model. It still works for reasons of backwards compatibility, but in such cases there are no guarantees that it will continue to work.
I have a word document with automatic numbering and bulleting.
I have selected the text where I need to convert automating numbering and/or bulleting to normal text.
In addition I need to keep both the formatting and numbers/bullets of the selected text.
What I have already tried:
cut the paragraphs and special pasted them (but it breaks formatting);
unpressed the "numbering"/"bulleting" button (but it erases all numbers and bullets);
used VBA-macro (but it returns an error):
Code (error, method or data member not found):
Sub convertNumbersAndBulletsToText()
Selection.ConvertNumbersToText
End Sub
What would you recommend me to do in order to keep both formatting and numbers/bullets?
You have practically done everything yourself!
This code will work:
Sub convertNumbersAndBulletsToText()
Selection.Range.ListFormat.ConvertNumbersToText
End Sub
Your example returns error because ConvertNumbersToText method doesn't work with Selection. It works with Range!
(look here: Change selected automatic numbered list to plain text in word)
Beware!
If you want to carry out many changes, you may find it easier to make them with ActiveDocument (look below).
But if want to do it manually (or through a loop),
then you'd better loop from the last element you want to convert till the first one
(not vice versa, because auto-numbers would then increment by one all the time)!
Small Tips
Personally I would recommend you to use this code instead:
Sub convertNumbersAndBulletsToText()
Dim myRange As Range
Set myRange = Selection.Range
myRange.ListFormat.ConvertNumbersToText
End Sub
Why this one? It is a little bit more flexible! Instead of Selection.Range you could use any other type of Range (ActiveDocument, ActiveDocument.Paragraphs, myRange.SetRange etc)
Here are some links from msdn to give you basic examples of Ranges: 1) Range Object (Word) (msdn), 2)
Range.SetRange Method (Word) (msdn).
Just for your information, you don't need to save VBA if you don't want to. You can use Immediate Window to launch VBA.
Press alt+f11 (VBA-editor), then ctrl+g (Immediate Window).
Paste the code bellow, press enter.
VoilĂ !
Code (for Immediate Window):
ActiveDocument.ConvertNumbersToText
(It converts auto-numbers and auto-bullets to normal numbers and bullets everywhere in ActiveDocument).
The result of any VBA here would be number+tab+text. If you want to have number+space+text you can:
either at the very end replace (press ctrl+h) this one .^t (dot and tab) for . (dot and whitespace),
or at the very beginning 1) select the list, 2) right click on it, 3) click "Adjuct list idents", 4) click "Follow number with: Space". (Look here: Adjust the spacing for a single list item (support.office))
You may need to have a leading zero in (auto-)numbering, then you can press ctrl+f9, write SEQ MyList \# "000" inside curly brackets, press alt+f9 to finish (look here: Insert fields in Word (support.office)). But this goes beyond the question, though you may find word fields really useful in some cases.
To sum up:
You can replace both bullets and numbers for plain text in Word:
for Selection (look above);
for ActiveDocument (look above);
with a Range (examples in msdn);
with a loop (examples are welcomed). But bear in mind that you are to loop from the end of the document to the beginning.
I'm trying to do something with a multiple selection. I wanna add some text before every selected paragraph but, when I select multiple discontinuous paragraphs, if I do Selection.Paragraphs.Count I always get "1".
How could I work with all paragraphs apart?
Example:
Paragraph1(Selected first)
Paragraph2
Paragraph3(Selected second)
What I got when I try to add some text at the beginning of these paragraphs:
Paragraph1
Paragraph2
TEXTParagraph3
What I really want to obtain:
TEXTParagraph1
Paragraph2
TEXTParagraph3
I'm working like this:
sub x()
dim p as paragraph
for each p in selection.paragraphs
p.range.insertbefore("TEXT")
next
End sub
Word simply cannot do what you'd like for it to do. Developers have wished for this since multiple selections were introduced in 2003 (I think it was, might have been version 2007). Word's object model simply does not support it.
If this is something you want to provide to the user to make life easier you'll need to give the tool a way to mark the paragraphs so your code can recognize them. You could provide a macro, for example, that assigns an incrementing bookmark name to each selection (the user selects, then runs your macro; repeat for each paragraph). Your code can then address each bookmark and perform the actions. To make this more user friendly you can assign the macro to a keyboard shortcut and/or a button in the Ribbon/QAT and/or the right-click menu.