I'm working on a Word Macro to streamline doing my University Mathematics and Statistics Coursework. Basically, selecting a group of equations and running it changes font size, line height and formats the paragraph in the way that I want to be common to all my maths/equations sections. It's great, but there's one little bit which I still have to do "manually", so to speak, which is right clicking and selecting "Align at equals".
Now the reason I'm asking this here and not on Super User is that I think I've exhausted all ways of doing this at the "record macro" stage. I found out how to access the right click menu without right clicking and accessed the "align at equals" option during record. Nothing was recorded.
Truth be told I'd prefer to code the lot anyway as it gives me more control. So, I'll post my code here and if anyone knows what line(s) of code I need to add to get it to replicate the "align at equals" command I would be extremely grateful.
Sub Equationiser()
'
' Equationiser Macro
'
'
With Selection.ParagraphFormat
.SpaceBefore = 12
.SpaceAfter = 12
.LineSpacingRule = wdLineSpace1pt5
End With
Selection.Font.Size = 20
End Sub
So, ideally just before the "With Selection.ParagraphFormat" section there would be some kind of "AlignAtEquals" command or whatever is needed so that, on one keypress, I would be able to align all the equals, set the line height to 1.5, place a 12 point space before and after the paragraph and change the font size to 20.
My absolute ideal would also be to programatically select all equation boxes that are in the same block, as "align at equals" is notoriously fussy and finicky as to when it will execute. That might also mean there may be a try and catch needed depending on whether trying to run "align at equals" when it wouldn't normally be available from the right click menu would do nothing or cause an error.
Any help on these two implementations would be gratefully appreciated but I'd happily settle for just the first.
I've built a solution that should address your needs, based on:
Looking through the equation to find the equal-sign.
Get the location of that equal-sign
Use that location to set the AlignPoint property of the OMath object
that is your equation
Use this MSDN reference if you want to explore more
Sub Equationiser()
'
' Equationiser Macro
'
'
Dim equationCounter As Long, charLoc As Long, FormattedTextLoc As Long
With Selection
For equationCounter = 1 To .OMaths.Count:
FormattedTextLoc = 0
For charLoc = 1 To Len(.OMaths(equationCounter).Range.FormattedText):
FormattedTextLoc = FormattedTextLoc + Len(.OMaths(equationCounter).Range.FormattedText.Characters(charLoc))
If .OMaths(equationCounter).Range.FormattedText.Characters(charLoc) = "=" Then
.OMaths(equationCounter).AlignPoint = (FormattedTextLoc - 1)
Exit For
End If
Next charLoc
Next equationCounter
End With
With Selection.ParagraphFormat
.SpaceBefore = 12
.SpaceAfter = 12
.LineSpacingRule = wdLineSpace1pt5
End With
Selection.Font.Size = 20
End Sub
I've done some brief testing that from what I can see this should be able to manage several code-blocks, i.e. when selecting 2 code-blocks it will align-at-equals all equations in the first block, then align-at-equals all equations in the second block (both blocks are not aligned with each oter) - is this your desired outcome to your request: My absolute ideal would also be to programatically select all equation boxes that are in the same block, as "align at equals" is notoriously fussy and finicky as to when it will execute.
Any idea why inserting break points and stop no longer stops my vba code from running?
The code runs ok all the way to the end (I tested it) but ignores break points and Stop.
Also step into just makes the code run in it's entirety, ignoring break points and stops.
When I close the workbook where the issue seems to originate from the same issue occurs in other macro workbooks.
if I completely close excel and re-open it with a normally working macro workbook the issue doesn't occur until I re-open the problem work book.
I added breakpoints on:
TotP1 = 0
of the following code:
Option Explicit
Private Country As String
Private Measure As String
Private P1 As String
Private P2 As String
Private TotP1 As Double
Private TotP2 As Double
Sub VennDisplayIt()
Dim SI() As String
Dim SICount As Integer
Dim x As Integer
Dim OSh As Worksheet
Dim BrandListBox As Object
Dim VennGroup As Shape
TotP1 = 0
TotP2 = 0
Set OSh = ThisWorkbook.Sheets("Venn")
Set BrandListBox = OSh.OLEObjects("BrandListBox").Object
ReDim SI(2, 0)
For x = 0 To BrandListBox.ListCount - 1
If BrandListBox.Selected(x) = True Then
'If UBound(SI) < 4 Then
ReDim Preserve SI(2, UBound(SI, 2) + 1)
SI(1, UBound(SI, 2)) = BrandListBox.List(x)
SI(2, UBound(SI, 2)) = x + 1
'End If
End If
Next x
If UBound(SI, 2) < 2 Then
BrandListBox.Selected(BrandListBox.ListIndex) = True
Exit Sub
ElseIf UBound(SI, 2) > 4 Then
BrandListBox.Selected(BrandListBox.ListIndex) = False
Exit Sub
End If
For x = 1 To UBound(SI, 2)
OSh.Range("o8").Offset(x, 0).Value = SI(1, x)
OSh.Range("o8").Offset(x + 5, 0).Value = SI(1, x)
Next x
For x = UBound(SI, 2) + 1 To 4
OSh.Range("o8").Offset(x, 0).Value = ""
OSh.Range("o8").Offset(x + 5, 0).Value = ""
Next x
SICount = UBound(SI, 2)
For x = 1 To OSh.Shapes.Count
If Right(OSh.Shapes(x).Name, 5) = "Group" Then
If LCase(OSh.Shapes(x).Name) = SICount & "waygroup" Then
Set VennGroup = OSh.Shapes(x)
OSh.Shapes(x).Visible = True
Else
OSh.Shapes(x).Visible = False
End If
End If
Next x
For x = 1 To SICount
VennGroup.GroupItems.Item(SICount & "WayBrand" & x).DrawingObject.Text = SI(1, x)
Next x
Country = ThisWorkbook.Sheets("Venn").Range("D4").Value
Measure = ThisWorkbook.Sheets("Venn").Range("E32").Value
P2 = ThisWorkbook.Sheets("Venn").Range("E31").Value
P1 = ThisWorkbook.Sheets("Selections").Range("B5").Value
End Sub
I've never heard of Stop not working, but I've heard about and experienced the breakpoint thing many times. When you compile VBA, it creates a p-code, which is used by the interpreter. You have the VBA syntax layer that you can see and the p-code layer that you can't see. When breakpoints stop working, it's because the p-code was corrupted. I don't know how or why it happened, but it did.
The fix is to export, remove, and reimport all of your modules. Exporting them creates a .bas file (plain text, really). When you re-import, the p-code is regenerated from scratch. If you have more than a couple of modules, get CodeCleaner (free add-in) and it will export and reimport automatically.
If one of the settings is unchecked then breakpoints will not work. "File/options/Current database/Application options/use access special keys" should be checked
Just to 'second' Tibo's comment: I had a problem where I had a form with about 5 different subroutines. One of them (attached to a button event) would not stop when I set a breakpoint. in 10 years of VBA writing, I've never seen that happen. Interestingly, breakpoints worked on all of the other subroutines in that form. After much head-scratching and searching, I came upon this post and Tibo's comment. I added a "Stop" command to the affected subroutine, ran the procedure (it stopped as it should have) and then breakpoints began working again! Hope this helps someone in the future.
If the breakpoints are in your code, then the code should stop running as soon as it hits that line. Possible causes of your problem:
a) The code never gets to the Breakpoint.
Seems highly unlikely seeing as you're breaking on the first line of your code. Maybe step through the sub (F8) just to check it's running as it should.
b) Your breakpoints have been wiped. Any line with a breakpoint should display as highlighted in red on your IDE. Your breakpoints can easily be wiped through, e.g. closing and opening the workbook (a screenshot would be really useful).
c) your workbook is broken in some way. It would be unlikely to break something as fundamental as stopping at breakpoints and still function normally. Are you sure your code is actually running?
Just sharing a funny thing which happened to me in case it helps someone. The mistake I did was that I simply took someone's method code meant for workbook open event and pasted it on Sheet1 excel object code area. So there was no possibility of Workbook_Open method getting fired ever.
Private Sub Workbook_Open()
Stop
On Error Resume Next
Call ActiveSheet.Worksheet_Activate
On Error GoTo 0
End Sub
What I was supposed to do is paste this method after double clicking ThisWorkbook node under Microsoft Excel Objects in Project pane as shown below:
Note: Side effect of copy-pasting others code can be freaky at times.
a) Double check that your breakpoints got disabled or not.
b) Double check that you added a conditional breakpoint or not
c) If you run your macro using C# code (using, the _Run2 command), breakpoints and stop doesn't work sometimes.
I have the problems as described above:
Stop and Breakpoints not working
Single step F8 worked, but code was not highlighted in yellow
Closing VBA editor did not help
My remedy: close VBA editor again, save Excel-file, open editor, back to normal
I've never faced this problem for years. Today for the first time I started using watch expressions with stopping when true.
This happens to me once in a while and the following solves the problem for me every time:
Create a Sub with only the command Stop in it. Run it. Then try your routine, the breakpoints and Stop commands should now work correctly.
Make sure that you do not have a named Range that matches the name of the Function or Subroutine you are calling. This will look like the Function or Subroutine is failing, but it is actually failing before the routine is ever called with an 'invalid cell reference'.
I had this problem as well. My solution was put an error in the code and run it. After I cleared the error the breakpoints started working again. That was weird.
I been writing code in VBA for many years but today I came across this problem for the first time. None of the solutions I found on the web worked but here's something simply you can use instead of Stop:
ErrCatch = 1 / 0
Still doesn't solve the breakpoints not working though...
I went int my vba code, added an enter (new blank line), then ran it again.
Voila! It ran the code and stopped at the breakpoint!
Not just me then! On a few occasions the yellow hi-lite stops a few lines beyond the breakpoint! I guess the code is running so fast it can't stop in time. :) As suggested above, I find adding "stops" here and there and also exporting & re-importing helps too.
I'm trying to add a little interaction to a PowerPoint presentation I'm working on. I'm written a little VB that will increase the size and position a particular chart object when the script runs. I'm tested the script in design mode and everything seems to work fine. When, however, I link my code to an action button and try to run it from within the slide show the code does not run. I do most of my VB in Excel so I have not run across this before. Can anyone suggest a fix for this. My code is set forth below:
Sub MoveChart23()
Dim s
For Each s In ActiveWindow.Selection.SlideRange.Shapes
If s.Name = "Chart 23" Then
s.Top = 50
s.Width = 620
s.Left = 50
s.Height = 400
End If
Next
End Sub
Thanks for your help.
Anyway, I think your problem is in the following line:
For Each s In ActiveWindow.Selection.SlideRange.Shapes
while you have no Selection in presentation mode. Depending on the way you run and control the whole presentation you should use something like this instead:
For Each s In ActiveWindow.Slides(1).Shapes
But if you need to refer to currently viewed slide you should go this way:
For Each s In SlideShowWindows(1).View.Slide.Shapes
at the moment I have a small application and need to take information from an object and display it into an excel file, using the Microsoft.office.interop class I've been able to write to the file, and it shows one by one the records being added, however about once every 3 times I try it, the spreadsheet stops filling somewhere between the 300th and 600th record, I have 6,000 in total and it's not breaking every time, I put a check after it finishes to see whether the last record is filled in but the code never reaches that point and I'm unsure of what's happening
I also don't know how to debug the problem as it'd mean going through 6,000 loops to check for it stopping... which might not even happen?
a little section of the code is here
loadExcel(incidents, WorkSheetName)
If WorkSheetName.Cells(DBObject.HighestInci + 1, 6) Is Nothing Then
MessageBox.Show("Failed to fill spreadsheet, Retrying now.")
loadExcel(incidents, WorkSheetName)
End If
above is the code calling and checking the method below
Private Sub loadExcel(ByVal incidents As List(Of Incident), ByRef WorkSheetName As Excel.Worksheet)
Dim i = 2
For Each inc As Incident In incidents
WorkSheetName.Cells(i, 1) = inc.DateLogged
WorkSheetName.Cells(i, 2) = inc.DateClosed
WorkSheetName.Cells(i, 3) = Convert.ToString(inc.DateLogged).Substring(3, 2)
i += 1
Next
End Sub
Thanks in advance
EDIT
I'm thinking loading it to a buffer of some sort then writing once they have all been updated would be the way to go instead of it currently loading and writing each separately? however I have no idea where to start for that?
I've fixed my problem, with what I had above Excel was opened and it started printing into the spreadsheet line by line, the problem is that any interactions with excel would cause the process to freeze
By adding an
ExcelApp.visible = false
before carrying out the process and an
ExcelApp.visible = true
afterwards, it all works and then opens the file afterwards
I want to make a special list of figures with use of VBA and here I am using the function
myFigures = ActiveDocument.GetCrossReferenceItems(Referencetype:="Figure")
In my word document there are 20 figures, but myFigures only contains the first 10 figures (see my code below.).
I search the internet and found that others had the same problem, but I have not found any solutions.
My word is 2003 version
Please help me ....
Sub List()
Dim i As Long
Dim LowerValFig, UpperValFig As Integer
Dim myTables, myFigures as Variant
If ActiveDocument.Bookmarks.Count >= 1 Then
myFigures = ActiveDocument.GetCrossReferenceItems(Referencetype:="Figure")
' Test size...
LowerValFig = LBound(myFigures) 'Get the lower boundry number.
UpperValFig = UBound(myFigures) 'Get the upper boundry number
' Do something ....
For i = LBound(myFigures) To UBound(myFigures) ‘ should be 1…20, but is onlu 1…10
'Do something ....
Next i
End If
MsgBox ("Done ....")
End Sub*
Definitely something flaky with that. If I run the following code on a document that contains 32 Figure captions, the message boxes both display 32. However, if I uncomment the For Next loop, they only display 12 and the iteration ceases after the 12th item.
Dim i As Long
Dim myFigures As Variant
myFigures = ActiveDocument.GetCrossReferenceItems("Figure")
MsgBox myFigures(UBound(myFigures))
MsgBox UBound(myFigures)
'For i = 1 To UBound(myFigures)
' MsgBox myFigures(i)
'Next i
I had the same problem with my custom cross-refference dialog and solved it by invoking the dialog after each command ActiveDocument.GetCrossReferenceItems(YourCaptionName).
So you type:
varRefItemsFigure1 = ActiveDocument.GetCrossReferenceItems(g_strCaptionLabelFigure1)
For k = 1 To UBound(varRefItemsFigure1)
frmBwtRefDialog.ListBoxFigures.AddItem varRefItemsFigure1(k)
Next
and then:
frmBwtRefDialog.Show vbModeless
Thus the dialog invoked several times instead of one, but it works fast and don't do any trouble. I used this for one year and didn't see any errors.
Enjoy!
Frankly I feel bad about calling this an "answer", but here's what I did in the same situation. It would appear that entering the debugger and stepping through the GetCrossReferenceItems always returns the correct value. Inspired by this I tried various ways of giving control back to Word (DoEvents; running next segment using Application.OnTime) but to no avail. Eventually the only thing I found that worked was to invoke the debugger between assignments, so I have:
availRefs =
ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem):Stop
availTables =
ActiveDocument.GetCrossReferenceItems(wdCaptionTable):Stop
availFigures = ActiveDocument.GetCrossReferenceItems(wdCaptionFigure)
It's not pretty but, as I'm the only person who'll be running this, it kind of works for my purposes.