VBA Macro no longer works in office 365 - vba

I have a word macro working fine in Office2013.
The macro reduces the height of the last page in a document to remove trailing blank space. Later I combine serveral of these documents (converted to XPS) to one doc - without blank areas due to empty spaces on the last pages.
Sub SetCurPageHeight(nHeight, nPage)
nHeight = PointsToCentimeters(nHeight)
nHeight = nHeight + 0.5
Dim strHeight As String
strHeight = CStr(nHeight)
strHeight = Replace(strHeight, ",", ".")
WordBasic.PageSetupPaper PaperSize:=9, TopMargin:="0", _
PageHeight:=strHeight, Orientation:=1, FirstPage:=0, _
OtherPages:=0, _
ApplyPropsTo:=1, FacingPages:=0, _
SectionStart:=nPage, _
SectionType:=1
End Sub
With Office365 the macro no longer works as expected. When I use it ALL pages are set to the given height - not only the last one.
I can't even find any documentation for "PageSetupPaper". And also no replacement for this functionality.
I thinmk there was a "page setup dialog" which had a "only this page" option - from that I recoreded the macro and adapted it for my needs.
Is there any documentation for PageSetupPaper - or has anyone a hint how to solve the problem with other code Office365 VBA.

You need to re-write the macro in a pure VBA without using WordBasic in the code. Read more about that in the Converting WordBasic Macros to Visual Basic article.
Also you may consider using the macro recorder to find the required properties and methods to get the job while you are doing the steps manually and recording them.

Perhaps the simplest approach if using Word's standard justification method is to use something like:
Sub Document_Minimise()
ActiveDocument.Compatibility(wdWPJustification) = True
End Sub
This applies WordPerfect justification to justified paragraphs in the document, compressing the text more than Word's own justification method. That alone may be sufficient to reduce the page count.

Related

Comment.Add in Word VBA (2019) is inconsistent in adding text to the comment

Context: I am using Word 2019 (Office 365 subscription, if that matters). I have added a series of buttons to my Review ribbon, each set to create a specific comment on some text. (Writing teacher. I make a lot of repeated comments.)
The structure for each comment macro is as follows:
Sub AddSomeComment()
Dim someComment As String
someComment = "Long explanation of some revision recommendation."
ActiveDocument.Comments.Add Range:=Selection.Range, Text:=someComment
End Sub
Problem: The comment balloon is always added, but it is frequently left blank. On some documents, every comment will work (1/10 maybe). On others, the first comment will work but all others will be left blank. A majority of documents will not place the text into the comment. All documents are saved as docx prior to commenting.
I have tried debugging and rewriting the code several times. I've hard coded strings in to each comment and gotten the same results. I have tried using a MsgBox() to verify that someComment has a string in it (it does).
I don't know why it might be behaving like that. Perhaps there's a "race" condition (the text is sent to the comment before it's been created).
Try it like this: create the comment and after it's been created assign the text. (Note: I'm on a mobile device so can't test for syntax errors)
Sub AddSomeComment()
Dim cmt as Comment
Dim someComment As String
someComment = "Long explanation of some revision recommendation."
Set cmt = ActiveDocument.Comments.Add Range:=Selection.Range
cmt.Range.Text = someComment
End Sub

Range accepts sometimes only semicolons instead of commas

I have reduced my problem to the following code example. I am using a German Excel version in which separators in normal Excel formulas are semicolons ";" instead of "," (e.g. =SUMME(A1;A3) instead of =SUM(A1,A3)).
Now the code which works different from time to time:
Sub CommasDoNotWorkAnymore()
Dim a()
Dim i%
a = Array("A1,A3,A5", "B1", "B2")
i = 0
Debug.Print Sheets(1).Range(a(i)).Address
End Sub
Normally, when starting Excel, this code works. But sometimes Excel seem to switch the accepted separators used in the Range() to semicolons untill I restart Excel. This occurs most times when rerunning the code after a runtime error.
Is this a general Excel bug? Does anybody know what is behind this behaviour? Is there some Excel-wide "local option" for the Range class?
EDIT: I just tried to convert the a(i) with CStr(a(i) but this does also not work. So no ByRef kind of problem...
If you want to control it, check first what separator is currently in use. What I guess is that you want to know the list separator:
Application.International(xlListSeparator)
Check other separators here:
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-international-property-excel
The other time I had a problem with identifying decimal separator in VBA. Finnally I was able to get it in this way:
Function GetVBAdecimalSep()
Dim a(0) As Variant
a(0) = 1 / 2
GetVBAdecimalSep = Mid(a(0), 2, 1)
End Function
Changing separator not always works. Please see this: Changing decimal separator in VBA (not only in Excel)
The best solution is to check/change locale, even temporary.
Application.LanguageSettings.LanguageID(msoLanguageIDUI)
gives the LCID which would be 1033 for English (US)

VB.Net equivalent for (CustomizationContext) in VBA

I'm busy with some word automation and have run into an issue whereby a context menu within a document has items in, that I wish to remove.
Once the document is open, through vba I can remove these items by running the following code;
[VBA]
Dim oContextMenu As CommandBar
Dim oContextMenuItem As CommandBarControl
'Make changes to the ActiceDocument only (this is needed to make any changes to this document).
CustomizationContext = ActiveDocument
For Each oContextMenu In ActiveDocument.CommandBars
If oContextMenu.Type = MsoBarType.msoBarTypePopup Then 'Loop through all the context menus of type (msoBarTypePopup)
For Each oContextMenuItem In oContextMenu.Controls
If (InStr(oContextMenuItem.Caption, "Smokeball")) Then
oContextMenuItem.Delete
End If
Next
End If
Next
If I execute this code and check the document, all contextMenu sub items that contain the text "smokeball" are removed.
When I try move this code to my VB.NET solution (I have no choice of language, so VB it is), I get errors on the CustomizationContext = ActiveDocument line (this line has to be there for it to affect the current document).
The error I get is CustomizationContext' is not a by reference property.
Does anyone know how to get just that ONE line equivalent for vb.net?
Thanks in advance.
EDIT: In case you need to see the vb.net sub:
Private Sub RemoveUnwantedContextMenuItems()
Dim oContextMenu As CommandBar
Dim oContextMenuItem As CommandBarControl
'Make changes to the ActiceDocument only (this is needed to make any changes to this document).
WordApplication.CustomizationContext = WordApplication.ActiveDocument 'This is the error.
For Each oContextMenu In WordApplication.CommandBars
If oContextMenu.Type = MsoBarType.msoBarTypePopup Then 'Loop through all the context menus of type (msoBarTypePopup)
For Each oContextMenuItem In oContextMenu.Controls
If (InStr(oContextMenuItem.Caption, "Smokeball")) Then
oContextMenuItem.Delete()
End If
Next
End If
Next
End Sub
PS - I have also already tried using the .AttachedTemplate as well as .Normal / .NormalTemplate
Jules pointed me in the right direction with his sample code.
After lots of playing around I noticed that somewhere in the solution, the [TYPE] of WordApplication was getting changed to a dynamic type of sorts, hence, it couldn't use CustomizationContext.
My solution was this:
I changed this line;
WordApplication.CustomizationContext = WordApplication.ActiveDocument
To this:
CType(WordApplication, Microsoft.Office.Interop.Word.Application).CustomizationContext = WordApplication.ActiveDocument
Forcing the types to be correct.
Simple solution but took some time.
Thanks to Jules for pointing me in the right direction.
(Points should go to you).

Is there any way to align text in message box in vb or vba?

Is there any way to align text into the center in msgbox in VB or VBA? Does VB have any functionality to do the same?
No. The MsgBox() function is simply a wrapper for the Windows MessageBox() function and as such has no stylistic control over the dialog beyond the icon.
If you want to change it any further than this, you will need to create your own window and show that instead.
On Windows Vista+ you can use TaskDialogs that allow a lot more control.
no, but you can cheat by using spaces.
msgbox(" your message")
VBA
Some notes: http://access.mvps.org/access/bugs/bugs0035.htm AND http://www.tek-tips.com/viewthread.cfm?qid=435428 However, it is not so difficult to build your own message box, which solves all your problems.
When you are building your strings you could pad them at the beginning and end with spaces to achieve a target length. If you're using excel the worksheet function rept is handy for this.
function pad_n_center(byval mystring as string, lenmax as integer) as string
dim pad_by as integer
dim pad as string
pad_by = (lenmax - len(mystring))/2
'some more code to finesse that?
pad = worksheetfunction.rept(" ",pad_by)
pad_n_center = pad & mystring & pad
end function
As mentioned before if the msgbox still doesn't look good you can use textbox shape object (or other objects) to get the desired effect.

Font of all headings in a Word Document

I am trying to retrieve the font name and size of all the headings from a word document. Any idea how to get it?
The basic structure will be something like below:
Public Sub ShowFontAndSize()
Dim singleLine As Paragraph
Dim lineText As String
For Each singleLine In ActiveDocument.Paragraphs
Debug.Print singleLine.Range.Font.Name
Debug.Print singleLine.Range.Font.Size
Next singleLine
End Sub
The catch will be that this won't sense if there are different fonts and sizes on the same line. If that's a possibility, you will need to add another loop with For Each singleCharacter In singleLine.Range.Characters inside of the paragraphs loop.
Edit: A trickier problem is what to do with this data once you've collected it. Building up an array seems like the natural fit, but VBA arrays are borderline useless, since basic methods like .append() require you to redim the whole array. See http://www.cpearson.com/excel/VBAArrays.htm for more info if you would like to go down that road.
The most straight forward solution is to open the document in Word and access the object model. This is traditionally done using VBA, but you can also use .NET (e.g. C# og VB.NET) by using VSTO (Visual Studio Tools for Office). Personally I find C#/VB.NET much better languages than VBA.
Once you have access to the object model you will have to enumerate paragraphs in the document. When you find a heading (perhaps defined by the style) you will have to figure out the formatting of the heading.
This is what I got from a brief skim of the MSDN page on "HeadingStyles":
MsgBox ActiveDocument.HeadingStyles(1).Style