Second Run of VBA WordDoc tables add does not set variable - excel

I have a VBA routine in Excel which opens a word.app. All the set variables work fine in the multiple runs except for one thing. I hope you can help me out!
The relevant code in my opinion:
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
'load format
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
Set WordDoc = WordApp.Documents.Add(Template:=FormatLocation & FormatFile)
Call MakeTableFields(OHIBSingleEntity, WordDoc)
WordDoc.SaveAs FileName:=SaveFile, FileFormat:=wdFormatXMLDocument, AddtoRecentFiles:=False
WordDoc.Close
WordApp.Quit
Set OHIBSingleEntity = Nothing
Set WordDoc = Nothing
Set WordApp = Nothing
-----------------------------------------------------------------------------
Private Sub MakeTableFields(EntityFields As Recordset, WordDoc As Word.Document)
'make table sub
Dim PropTbl As Word.Table
Dim RangeCT As Word.Range
Set RangeCT = WordDoc.Content
With RangeCT.Find
.Text = "#InvoegenTabelISB"
.Format = False
.Wrap = wdFindContinue
.MatchWildcards = False
.Execute
End With
Recordcounter = EntityFields.RecordCount
'Problem is here:
Set PropTbl = WordDoc.Tables.Add(RangeCT, RoundUp(Recordcounter / 2, 0), 4)
'after this formatting and filling the just created table with the EntityFields dataset
Set RangeCT = Nothing
Set PropTbl = Nothing
End Sub
The first run it works as it should. The second time it runs everything works except formatting and filling the table. As far as I can trace it, it looks like Set PropTbl does not work. Creating the table works. But the next lines are failing/skipped. When I close the Excel with this VBA and open it again, it again works fine for the first run. Second run fails again.
What I tried was to make the table and then Set PropTbl:
WordDoc.Tables.Add RangeCT, RoundUp(Recordcounter / 2, 0), 4
Set PropTbl = WordDoc.Tables(1)
This also gives the same behavior. It almost looks like something is kept in the memory while keeping running excel. But I don't know how to debug the memory while all VBA routines are executed and finished.
Does anybody know how to fix or debug this?

Really wierd, but the fault is not in the posted code
This does work for the first run, but it fails the second time:
With PropTbl.Borders
.LineStyle = Options.DefaultBorderLineStyle
.LineWidth = Options.DefaultBorderLineWidth
.Color = Options.DefaultBorderColor
End With
With PropTbl.Borders(wdBorderLeft)
.LineStyle = Options.DefaultBorderLineStyle
.LineWidth = Options.DefaultBorderLineWidth
.Color = Options.DefaultBorderColor
End With
With PropTbl.Borders(wdBorderBottom)
.LineStyle = Options.DefaultBorderLineStyle
.LineWidth = Options.DefaultBorderLineWidth
.Color = Options.DefaultBorderColor
End With
With PropTbl.Borders(wdBorderRight)
.LineStyle = Options.DefaultBorderLineStyle
.LineWidth = Options.DefaultBorderLineWidth
.Color = Options.DefaultBorderColor
End With
With PropTbl.Borders(wdBorderVertical)
.LineStyle = Options.DefaultBorderLineStyle
.LineWidth = Options.DefaultBorderLineWidth
.Color = Options.DefaultBorderColor
End With
With PropTbl.Borders(wdBorderHorizontal)
.LineStyle = Options.DefaultBorderLineStyle
.LineWidth = Options.DefaultBorderLineWidth
.Color = Options.DefaultBorderColor
End With
fix was simple:
PropTbl.Borders.Enable = True
Gives the same result. Wierd thing was that it just fails with no error. The only hint I got was from a hover tip over the Options.DefaultBorderLineStyle which gives a hint that the servercomputer was not reachable...?
Anyway, it is solved.

Related

ExcelApp.Visible causing Error 91 and I can't figure out how to fix it

A little background:
A former employee wrote a VBA program to run in AutoCAD to generate G-code based off of CAD entities. The immediate problem is that it currently only runs in AutoCAD 2002 on a computer running Windows XP on a virtual desktop. Obviously, that doesn't work so I'm trying to get it to work on BricsCad V21. My current issue is that I keep getting a Run time error 91 at the following place and I do not understand what the issue is or how to overcome it.
Please note that I am a VERY beginner programmer and am still trying to wrap my head around how all of this works. Any help you can provide would be most appreciated.
Public ExcelApp As Excel.Application
Public wbkObj As Excel.Workbook
Public shtObj As Excel.Worksheet
Public rngObj As Excel.Range
These are the relevant declarations at the beginning of the program
Sub CAM_A_CHEST()
Set ExcelApp = CreateObject("Excel.Application")
Set wbkObj = ExcelApp.workbooks.Add
Set shtObj = ExcelApp.Worksheets(1)
If Err <> 0 Then
MsgBox "Could not start Excel", vbExclamation
End
Else
ExcelApp.Visible = True
Application.Visible = True
ExcelApp.ScreenUpdating = True
Set rngObj = shtObj.Range(Cells(1, 1), Cells(1, 5))
With rngObj
.NumberFormat = "0"
.Font.Name = "Arial"
.Font.FontStyle = "Bold"
.Font.Size = 10
'.Font.ColorIndex = xlAutomatic
End With
With shtObj.Range(Cells(2, 1), Cells(2000, 13))
.NumberFormat = "0.000"
.Font.Name = "Arial"
.Font.FontStyle = "Regular"
.Font.Size = 9
.Value = ""
End With
With shtObj.Range(Cells(2, 5), Cells(2000, 5))
.NumberFormat = "0"
End With
shtObj.Range("A1:D1").Select
Selection.NumberFormat = "General"
shtObj.Cells(1, 1).ColumnWidth = 18
shtObj.Cells(1, 1) = "Layer"
shtObj.Cells(1, 2) = "Center X"
shtObj.Cells(1, 3) = "Center Y"
shtObj.Cells(1, 4) = "Diameter"
shtObj.Cells(1, 5) = "Sort"
shtObj.Cells(1, 7).Font.FontStyle = "Bold"
shtObj.Cells(1, 7).Font.Size = 10
Range("A2").Select
ActiveWindow.FreezePanes = True
End If
'ExcelApp.Visible = False
transZ$ = "2.00"
divNum$ = ""
grpNum$ = "0"
Load UserForm1
Load UserForm2
Load UserForm3
Load procUserForm
Call UserForm_Initialize
That is the chunk of code that opens Excel, formats the Worksheet, and prepares for inputs from AutoCAD. Later on in the code, The following Sub is called:
Sub CAM_TopAndBottomBoards()
Dim I As Integer
Dim mspaceObj As AcadObject
Dim centerPoint As Variant
Dim ExcelApp As Excel.Application
increment = 0
Call InitializeCounters
SelectStuff:
'Find entities representing Pitman Holes, Pipe Holes, etc., among items selected,
' dump data into Excel sheet
ExcelApp.Visible = True
It's that last line that is generating the error.
At this point I've spent a couple of days on this issue and I'm completely stuck. Help!

Accessing table data frequently

I am trying to read a table from a worksheet and storing in an listobject. I need to use this table data multiple time and I dont want to access worksheet every time I need table data. I think accessing worksheet everytime will slow down the performance.
Also I need to refer table data based on header name.
I was thinking of writing something like this.
public Tbl_MyTable as listobject
public Arr as variant
Set Tbl_MyTable = Workbooks("Myworkbook").worksheets("Myworksheet").ListObjects("Tbl1")
tRows = Tbl_MyTable .DataBodyRange.Rows.Count
for i=1 to 10
config= ArrConfig(i)
call readtable(tRows, config)
Set Destination = workbooks("x").sheets("y").Range("A2")
Destination.Resize(1,UBound(Arr, 1)).Value = Arr
'Create the table based on the populated data.
Set populated_area = Destination.CurrentRegion
Set Create_Table = .ListObjects.Add(xlSrcRange, populated_area, , xlYes)
Create_Table.name = (.name & "_tbl")
Create_Table.TableStyle = "TableStyleMedium15"
'Select this newly created table and do some data reformating
With ActiveSheet.ListObjects("" & Tbl_name & "").Range.Select
'Change entire Table font
With Selection.Font
.name = "Calibri Light"
.Size = 10
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
.ThemeFont = xlThemeFontMajor
End With
End with
...
...
...
'Inside Sub readtable
For i = 1 To tRows
if config= A
Arr(i) = Range("Tbl_MyTable[Header1]")(i).Value
else if config =B
Arr(i) = Range("Tbl_MyTable[Header2]")(i).Value
else
Arr(i) = Range("Tbl_MyTable[Header3]")(i).Value
end if
.
.
Problem is that it works only for first iteration of top level loop.
Next time I get following error (Somehow I am getting multiple errors every time I run it. Not all appear everytime)
Run-time error '1004' : Method 'Range' of object'_Global' failed
Error number: 90 Subscript out of range
Any idea what might be wrong here. I guess looking this code again and again I am hitting a wall now. I need another set of eyes to help me.

Stopping Linked/Embedded Objects Excel VBA

I have some code in Excel which updates a Word document and then saves it depending on the information in the cells. The only issue is that occasionally there's an error which pops up
Office is still updating linked or embedded objects for this workbook.
when the code is all completed successfully.
There are no other linked or embedded objects in the workbook.
This error was being shown when running the script manually before I added the button, so it doesn't make sense for it to be related to the button itself.
I am working on this independently meaning no others could be editing it at the same time. I click the button/run it, let it run, it freezes after closing Word (the last line of code) and then about 10secs later that error comes up.
I've attempted to add UpdateLinks:=0 and UpdateLinks:=false to the code but everywhere I put it it seems to not like having it there. I am not sure of how else to fix this but it cannot be an Excel/Word setting as a number of users will be utilising this.
Here's the current code:
Sub Button3_Click()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim msWord As Object
Dim msWordDoc As Object
Set msWord = CreateObject("Word.Application")
msWord.Visible = True
Set msWordDoc = msWord.Documents.Open("/Users/Aafrika/Desktop/Test.docx")
With msWordDoc
With .Content.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "<date>"
.Replacement.Text = Format(ws.Range("C1").Value2, "dd/mm/yyyy")
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
.Text = "<amount>"
.Replacement.Text = Format(ws.Range("C2").Value2, "currency")
.Forward = True
.Wrap = 1 'wdFindContinue (WdFindWrap Enumeration)
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
.SaveAs Filename:="/Users/Aafrika/Desktop/" & ws.Range("C3"), Password:="Password", FileFormat:=12 'wdFormatXMLDocument
DoEvents
.Close (False)
End With
msWord.Quit
End Sub
Hoping you can all shed some light on how to handle this!
The problem comes from Excel not being able to correctly release the Word objects. This is something that always should be done conscientiously when running another program through VBA ("automation" is one technical term used for this).
When you create objects from another program, in the background VBA creates "pointers" (links) to these objects. If they aren't expliclty released - in the reverse order they were created - this can "hang" VBA. There are various ways this can manifest itself - this is the first time I've seen this particular error and a quick google search doesn't turn up many examples. Possibly, this is an error that's new in Office 365/2016/2019...
The button (embedded object) has finished (reached End Sub) but hasn't released the objects it was working with, so Excel is waiting for that to happen.
The following code, modified from that in the question, shows how to release the objects created in the code (near the end). It involves Set [object] = Nothing for both the Word.Document and Word.Application objects, in the reverse order they were created at the beginning of the code.
Sub Button3_Click()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim msWord As Object
Dim msWordDoc As Object
Set msWord = CreateObject("Word.Application")
msWord.Visible = True
Set msWordDoc = msWord.Documents.Open("/Users/Aafrika/Desktop/Test.docx")
With msWordDoc
'Code here to work with the document
'Removed to better see the problem solution
.SaveAs Filename:="/Users/Aafrika/Desktop/" & ws.Range("C3"), Password:="Password", FileFormat:=12 'wdFormatXMLDocument
DoEvents
.Close (False)
End With
'''Clean up the non-Excel objects
Set msWordDoc = Nothing
msWord.Quit
Set msWord = Nothing
End Sub

Excel keeps "running" while asking SAP GUI to export spreadsheet

I have a problem with a Excel VBA code that constantly get stuck in 'running' when I execute the code, see figure
The Purpose of the code is:
Log into SAP
Execute a transaction (in this case IW73)
Export a Spreadsheet as .txt
The Problem after closing the SAP session the Excel get stuck in "Running". We have tried running it on different computers with the same (Stuck in 'Running') error.
Code:
Sub Logontrial()
Dim SapGuiApp As Object
Dim oConnection As Object
Dim SAPCon As Object, SAPSesi As Object
Dim SapGuiAuto As Object, SAPApp As Object
If SapGuiApp Is Nothing Then
Set SapGuiApp = CreateObject("Sapgui.ScriptingCtrl.1")
End If
If oConnection Is Nothing Then
Set oConnection = SapGuiApp.OpenConnection("5.1.1 AP1 ERP Production", True)
End If
If SAPSesi Is Nothing Then
Set SAPSesi = oConnection.Children(0)
End If
Application.DisplayAlerts = False
With SAPSesi
SAPSesi.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "500"
SAPSesi.findById("wnd[0]/usr/txtRSYST-BNAME").Text = "UserName"
SAPSesi.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = "Password"
SAPSesi.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "EN"
SAPSesi.findById("wnd[0]/usr/txtRSYST-LANGU").SetFocus
SAPSesi.findById("wnd[0]/usr/txtRSYST-LANGU").caretPosition = 2
SAPSesi.findById("wnd[0]").sendVKey 0
' start extraction
On Error GoTo Resume1
' DoEvents
SAPSesi.findById("wnd[0]").maximize
SAPSesi.findById("wnd[0]/tbar[0]/okcd").Text = "/nIW73"
SAPSesi.findById("wnd[0]").sendVKey 0
SAPSesi.findById("wnd[0]/usr/ctxtSWERK-LOW").Text = "GB10"
SAPSesi.findById("wnd[0]/usr/ctxtSWERK-LOW").SetFocus
SAPSesi.findById("wnd[0]/usr/ctxtSWERK-LOW").caretPosition = 4
SAPSesi.findById("wnd[0]").sendVKey 8
SAPSesi.findById("wnd[0]").sendVKey 0
SAPSesi.findById("wnd[0]/mbar/menu[0]/menu[11]/menu[2]").Select
SAPSesi.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[1,0]").Select
SAPSesi.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[1,0]").SetFocus
SAPSesi.findById("wnd[1]/tbar[0]/btn[0]").press
SAPSesi.findById("wnd[1]/usr/ctxtDY_FILENAME").Text = "DataImport1.txt"
SAPSesi.findById("wnd[1]/usr/ctxtDY_FILENAME").caretPosition = 15
SAPSesi.findById("wnd[1]/tbar[0]/btn[11]").press
SAPSesi.findById("wnd[0]/tbar[0]/okcd").Text = "/n"
SAPSesi.findById("wnd[0]").sendVKey 0
Set SAPSesi = Nothing
Set oConnection = Nothing
Set SapGuiApp = Nothing
End With
' This part after closing the SAP session it get stuck.
Resume1:
Application.DisplayAlerts = True
Set SAPSesi = Nothing
Set oConnection = Nothing
Set SapGuiApp = Nothing
Exit Sub
End Sub
Thanks in advance
//Patrick
Disclaimer: This is not quality code, and most probably one day someone can put some bunch of hate towards you.
Before finding something better, try the following, it should work. Simply write End here:
Set SAPSesi = Nothing
Set oConnection = Nothing
Set SapGuiApp = Nothing
End
Then look for a better solution.

setting color to a comment's characters in vba

I need to copy a cell in Excel from one range to another range's comment, while keeping its format (size, bold, color, italic...).
My piece of code works, except for color, which throws a Run-Time error '1004':
Font size must be between 1 and 409 points.
Which is strange, because size works, and if I comment out color lines (') it works.
Here is my code:
Option Explicit
Function Comment_Format(ByVal Rg_Value As Range, ByVal Rg_Com As Range) As Comment
Dim i As Long, a As Long
If Rg_Com.Comment Is Nothing Then Rg_Com.AddComment
With Rg_Com.Comment
.Text Text:=Rg_Value.Value2
.Shape.TextFrame.AutoSize = True
End With
For i = 1 To Len(Rg_Value.Value2)
With Rg_Com.Comment.Shape.TextFrame.Characters(i, 1).Font
.Size = Rg_Value.Characters(i, 1).Font.Size
'a = Rg_Value.Characters(i, 1).Font.Color
'If a > 0 Then .Color = a ' <<<<<<<<<<<<<<< this line shows the error !!
.FontStyle = Rg_Value.Characters(i, 1).Font.FontStyle
End With
Next i
Set Comment_Format = Rg_Com.Comment
End Function
Sub test()
Dim com As Comment
Set com = Comment_Format(Range("a1"), Range("b1"))
End Sub
Thanks for your help.
I had better luck using ColorIndex rather than Color and coloring first:
Sub MAIN2()
Call Comment_Format(Range("a1"), Range("b1"))
End Sub
Sub Comment_Format(Rg_Value As Range, Rg_Com As Range)
Dim i As Long
With Rg_Com
.ClearComments
.AddComment
.Comment.Text Text:=Rg_Value.Text
L = Len(Rg_Value.Text)
For i = 1 To L
.Comment.Shape.TextFrame.Characters(i, 1).Font.ColorIndex = Range("A1").Characters(i, 1).Font.ColorIndex
Next i
End With
For i = 1 To L
With Rg_Com.Comment.Shape.TextFrame.Characters(i, 1).Font
.Size = Rg_Value.Characters(i, 1).Font.Size
.Bold = Rg_Value.Characters(i, 1).Font.Bold
.Italic = Rg_Value.Characters(i, 1).Font.Italic
End With
Next i
End Sub
Which for me gave:
EDIT#1:
There appears to be a bug in Excel 2007 / Win 7 in the processing of Color with Comments
I finally found the solution and why a color line of code would rise a 'size' error.
I did like you, first color it all and then a second loop,
but added the autosize before the first loop (because my text is BIG) , then color loop,
then the 2nd loop (including size),
and then doing a second autosize=true because of course size changed !
i think its kind of like trying to select a cell in a hidden sheet, just applyed to comments
(the color property might rewrite every active pixel color but he cant 'read' a hidden pixel (being out of comment's shape size), am i making any sense to you?)
final code, working (any size of text):
Option Explicit
Function Comment_Format(ByVal Rg_Value As Range, ByVal Rg_Com As Range) As Comment
'Set Rg_Value = Range("A1") 'origin of the text
'Set Rg_Com = Range("b1") 'destination cell containing the comment
Dim i As Long 'simple loop counter
Dim ff As Font 'i used a variable for the long repeating garbage code (Rg_Value.Characters(i, 1).Font)
Dim L As Long ' lenght of text (mine is 508 in my sample)
If Rg_Com.Comment Is Nothing Then Rg_Com.AddComment
With Rg_Com
.ClearComments
.AddComment
With .Comment
.Text Text:=Rg_Value.Text
.Shape.TextFrame.AutoSize = True '<<< just to make all text visible in one comment, all chars having the basic size
End With
End With
'On Error Resume Next
L = Len(Rg_Value.Text)
For i = 1 To L
Set ff = Rg_Value.Characters(i, 1).Font
With Rg_Com.Comment.Shape.TextFrame.Characters(i, 1).Font
.ColorIndex = ff.ColorIndex
End With
Next i
For i = 1 To L
Set ff = Rg_Value.Characters(i, 1).Font
With Rg_Com.Comment.Shape.TextFrame.Characters(i, 1).Font
.Size = ff.Size
.Bold = ff.Bold
.Italic = ff.Italic
.Underline = ff.Underline
End With
Next i
Rg_Com.Comment.Shape.TextFrame.AutoSize = True ' <<< now chars of the comment's text already have different sizes, and i need to resize the shape
'On Error GoTo 0
Set Rg_Value = Nothing
Set Rg_Com = Nothing
End Function
Sub test()
Dim com As Comment
With Application
.EnableEvents = False
.ScreenUpdating = False 'tryed to make it faster, but still uber slow (25 seconds for my 508 characters sample text)
.Calculation = xlCalculationManual
End With
Set com = Comment_Format(Range("a1"), Range("b1"))
Beep 'wakes me up when the looping is over
Set com = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
End Sub

Resources