I have a main sub that I am using to set up my worksheets and data for analysis in other subroutines. As part of this I am turning some imported data into a table(data was imported from a CSV file) and placed into "IncidentsData" worksheet. The code for the entire module compiles. However, when I step through the module I get "Run-Time Error '5': Invalid procedure call or argument" on the line where I format the imported data into a table at:
Worksheets("IncidentsData").ListObjects.Add(xlSrcRange, ISDRange, , xlYes).Name = "IncidentsDataTable"
Here is the overall subroutine:
Public Sub Categorise_Incidents()
Dim incidentsData1 As ListObject
Set Commodity = Worksheets("CommoditySheet").ListObjects("Table1")
Set QEListByGenus = Worksheets("QEListByGenus")
Set Results = Worksheets("Results")
Set IncidentsDataSheet = Worksheets("IncidentsData")
ISDRange = IncidentsDataSheet.UsedRange
Worksheets("IncidentsData").ListObjects.Add(xlSrcRange, ISDRange, , xlYes).Name = "IncidentsDataTable"
Set incidentsData1 = IncidentsDataSheet.ListObjects("IncidentsDataTable")
initialiseDictionaries
MainSearchLoop QEListByGenus, incidentsData1, dictQENSGenus
End Sub
I have gone to a number of sites to work out how to do this action including:
1. the stack overflow pages on runtime error 5 in excel vba - most of these seem to be specific to pivot tables and didn't tell me what I was doing wrong
2. https://msdn.microsoft.com/en-us/vba/excel-vba/articles/listobjects-object-excel
3. stack overflow questions on creating a table in VBA How to create a table using vba?
4. analysistabs on creating a table in excel vba
https://analysistabs.com/excel-vba/tables-examples/
Plus a bunch of others. Unfortunately, they haven't helped me work out what I am doing wrong. Any help would be greatly appreciated.
Cheers, S26
Edited: to include .Name as that also does not work and throws a runtime error and to fix typos/errors.
First, change xlSrcERange and lYes to xlSrcRange and xlYes.
You're missing the .Name at the end of Worksheets("IncidentsData").ListObjects.Add(xlSrcRange, ISDRange, , xlYes). You haven't specified which property of the newly created table you want to be "IncidentsDataTable".
Alternately, you can do this:
Set incidentsData1 = Worksheets("IncidentsData").ListObjects.Add(xlSrcRange, ISDRange, , xlYes)
incidentsData1.Name = "IncidentsDataTable"
If you take that approach, it looks like you don't need to change the Name at all.
Related
I'm currently receiving a 'Linked File Not Available' error when trying to manually open datasets for embedded charts in Word after successfully updating these datasets via a VBA script. I am trying to build a project which will allow users to automatically update a series of embedded charts based on a user defined worksheet which is produced monthly.
In order to support this project, I've been trying to find a way in which I can update chart data in Word using VBA while avoiding the ChartData.Activate method (eventually crashes the program due to the burden of successive open / close actions [context: I have around 300 charts in the largest of these reports]).
I've attempted to update the data using a direct call to the ChartData.Workbook and ChartData.ActivateChartDataWindow both of which allow me to successfully update the data. Following the successful update however, I get the below error when trying to access the dataset manually and can no longer access it via the Macro:
Linked File Not Available
I know I am probably missing something simple, or perhaps am approaching this in the wrong way by going through Word but wanted to throw it out there to see if anyone has a solution which could resolve / explain what's causing the loss of these 'links' to embedded datasets?
Chart Screenshot (Front)
Chart Screenshot (Data)
To try and streamline testing; I've created a stripped down version of the overall code which I've been using to try and troubleshoot:
Dim x As Integer 'Counter used to breakout of routine once 1 chart updated.
Dim strChartTitle As String
Dim objChart As InlineShape
Dim objTargetWorkbook As Workbook
Dim objTargetWorksheet As Worksheet
x = 0
For Each objChart In ActiveDocument.InlineShapes
strChartTitle = objChart.Chart.ChartTitle.Text
If x = 1 Then
Exit Sub
ElseIf strChartTitle Like "EHR Transactions Summary (By Endpoint)*" Then
'objChart.Chart.ChartData.Activate
objChart.Chart.ChartData.ActivateChartDataWindow
Set objTargetWorkbook = objChart.Chart.ChartData.Workbook
Set objTargetWorksheet = objTargetWorkbook.ActiveSheet
objTargetWorksheet.Range("C1:D11").Copy objTargetWorksheet.Range("B1")
objTargetWorksheet.Range("D1").Value = DateAdd("m", 1, objTargetWorksheet.Range("C1").Value)
x = 1
objTargetWorkbook.close
End If
Next objChart
Problem:
Couldn't find a way to update data on a large number of charts using vba without utilising the Chart.ChartData.Activate or Chart.ChartData.ActivateChartDataWindow commands which either caused crash due to CPU load on successive load / unload (former method) or broke links between the embedded charts and their datasheets (latter method).
Solution:
Solution was provided in part by #Slightly Snarky in comment to original question / problem post. Despite Microsoft's documentation, it is possible to update data within Chart workbooks without the need to call an activate command by referencing the workbook and worksheet directly.
Re-wrote script to utilise the new method and confirmed not only did this allow me to edit data; it was able to do so while avoiding the performance hit inherent in the repeated open / close events caused by the two above methods.
On testing; one problem did come up in that MS-Word would spin up a new Excel sub-process each time the code referenced a different chart without killing the previous sub-process. Given these reports have up to 300 charts, this inevitably caused the routine to crash once enough sub-processes had built up against the CPU.
To resolve this issue, I tweaked the code to include a ChartData.Workbook.Close command after each chart update completes which has helped keep CPU burden to a minimum and prevented crashes due to overloading with Excel sub-processes.
Dim strChartTitle As String
Dim objChart As InlineShape
For Each objChart In ActiveDocument.InlineShapes
strChartTitle = objChart.Chart.ChartTitle.Text
If strChartTitle Like "EHR Transactions Summary (By Endpoint)*" Then
With objChart.Chart.ChartData.Workbook.Worksheets(1)
.Range("C1:D11").Copy objChart.Chart.ChartData.Workbook.Worksheets(1).Range("B1")
.Range("D1").Value = objChart.Chart.ChartData.Workbook.Worksheets(1).Range("D1").Value = DateAdd("m", 1, objChart.Chart.ChartData.Workbook.Worksheets(1).Range("C1").Value)
End With
objChart.Chart.ChartData.Workbook.close
End If
Next objChart
I want to copy from Excel to MS Project some data about a project. These data are gathered in a table in Excel and each column has a title describing the data below.
I need to identify the correct column from which extracting the data, but the method I tried gives me an error which I can't solve.
With the following code I'm looking to identify which columns contain the tasks of the project:
Set taskPos = Worksheets("Sheet1").Range("A1:AA2").Find("Task")
ColTask = taskPos.Column
ColTask should be the column containing the tasks from which I'd like to iterate the elements below.
For i = 2 To 10
exTask = Worksheets("Sheet1").Range("ColTask" & i).Value
Next i
With this method I get a
runtime error 1004 vba application defined or object
and I don't really know how to solve it.
Does anyone have an idea?
Thanks in advance
I have an VBA Macro that at times requires me to create a new slide with a new embedded excel spreadsheet, then edit that spreadsheet. A simplified version of this code:
Dim sld As Slide
Dim shp As shape
Dim pptWorkbook As Object
Set sld = ActivePresentation.slides.add(ActivePresentation.slides.Count + 1, ppLayoutBlank)
Set shp = sld.Shapes.AddOLEObject(100, 100, 100, 100, "Excel.Sheet")
DoEvents
If shp.Type = msoEmbeddedOLEObject Then
'Error thrown here
Set pptWorkbook = shp.OLEFormat.Object
pptWorkbook.Sheets(1).Cells(1, 1).value = "Stuff"
End If
About half of the time running this code results in the error:
Method object of object OLEFormat failed
This occurs on the shp.OLEFormat.Object call, I believe that this is due to "AddOLEObject" not creating the excel object in time to provide access to the property(but this is just a hypothesis). I have tried various ways of getting around this by error handling and sleep functions but so far I have been unable to create a new excel object and modify its contents within the same function without generating some error.
So my question is: How do you, with VBA, add a new embedded excel spreadsheet within a PowerPoint document and edit its contents within the same function/sub?
Update 1
I have successfully run this code on other machines, so this issue may be environmental, related with my system, and not an issue with my methodology. It also could be permission related, similar to This Post.
Update 2
I have reinstalled Office, restarted, run PowerPoint as administrator, and have added logic to account for the issue detailed in This post. Still no progress, I wonder if anyone can replicate the error that I am receiving?
I fixed the issue by resetting all my office settings by deleting all related keys in the registry(As Detailed Here):
HKEY_CURRENT_USER\Software\Microsoft\Office
After further investigation it turned out the reason I was getting this error message was because I had installed the "OLAP PivotTable Extensions"(link) add in to excel, for some reason this was conflicting with the "AddOLEObject" method. So simply deleting the registry key for the extension effectively removed the extension from excel and fixed my issue. The same effect was also observed when the extension was fully uninstalled.
HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\OlapPivotTableExtensions2016
I have a Word .dot file which works in older versions of Word but fails with error 432 when run in Word 2013.
When I debug the code I have the line:
Load customerForm
And VBA shows the error:
Run-time error '432': File name or class name not found during Automation operation
The project "pennyscode" includes "Module1" which contains the function being debugged, "ThisDocument" and a form called "customerForm".
I have tried changing the name to "pennyscode.customerForm" but this doesn't make any difference.
This code is being called from a Sub function which is called from Document_New().
Updates
I can place a breakpoint on the Load customerForm line and demonstrate that it is the line that is causing the problem. If at this point I mouse over the word "customerForm" VBA comes up with
customerForm = <Object variable or With block variable not set>
If I delete/skip the Load line then the next line is customerForm.Show and that produces the same error.
If I just open the .dotm file and then use Alt-F11 to open VBA, I can look at the code for selectCustomer, list properties/methods and customerForm appears in the list.
Additional Note
I believe that within the Load function it must be calling GetObject and it is this that is failing. It is as if VBA can't find the customerForm object even though it appears in the project.
I've posted the full code of the function being called from Document_New below.
Sub selectCustomer()
Dim Doc As Document
Set Doc = Application.ActiveDocument
If Doc.CustomDocumentProperties.Item("Customer") = "Nothing" Then
Load customerForm
customerForm.Show
Unload customerForm
Doc.Fields.Update
a$ = Doc.CustomDocumentProperties.Item("InvoiceNumber")
a$ = customerForm.pathBox.Value + "\" + a$
Doc.SaveAs (a$)
End If
End Sub
I've also posted the full .dotm (Excel 2013) and .dot (previous excel) and some sample data (.xls) here:
Dropbox/Public/Invoice 2015-16.dotm
Dropbox/Public/Invoice 2015-16.dot
Dropbox/Public/data.xls
Update
I've not had much luck making progress on this question. Can anyone suggest an approach to investigating this? Or how I might improve the information on the question?
I finally managed to fix this, and I have a few learnings.
Firstly the debugger shows the error as occurring on the Load customerForm line, but this is actually not the case.
The customerForm has an _Initialize function which loads data into it before it is displayed. This function was failing with but the debugger stops on the wrong place.
I was able to debug this more effectively by putting a breakpoint on the start of the _Initialize sub and then stepping through the code.
Once I had discovered this I realized that the code was failing to find the XLSX file due to a wrong path, thus causing the run-time error.
Once I'd fixed up all the paths, I then hit a second error: runtime error '9' which is a subscript problem. This also reported on the Load customerForm line and was also due to a problem with the _Initialize function.
This was the true source of the problem, and demonstrated a functional change between Office 2013 and previous versions of Office.
My code was opening an XLSX file and attempting to read data from it:
Dim myXL As Object
Dim myWS As Object
Set myXL = GetObject("C:\Test\data.xlsx")
myXL.Application.Visible = True
myXL.Parent.Windows(1).Visible = True
Set myWS = myXL.Application.Worksheets("Customers")
The run-time error 9 was due to the index of the Windows property, as their were no windows. In previous versions of Office, there was a single window, with 2013 the array is empty.
After much messing about I tried adding this line:
myXL.Activate
before accessing the Windows() array. Once that was executed Windows(1) existed and the code worked as before.
Hope this can help someone else struggling with similar problems.
I'm using MS-Access 2010 and Autocad 2012 64bit and work in manufacturing.
I want to be able to at the very least, populate fields in a title block, better still I would like to use data in my access database to write data into a sheet set (the current system works by reading the sheet set values such as sheet title and number into my title block).
The following code is all I have at the moment and it will open autocad and write the date into the command line.
Private Sub OpenAutocad_Click()
Dim CadApp As AcadApplication
Dim CadDoc As AutoCAD.AcadDocument
On Error Resume Next
Set CadApp = GetObject(, "AutoCAD.Application")
If Err.Number <> 0 Then
Set CadApp = CreateObject("AutoCAD.Application")
End If
On Error GoTo 0
CadApp.Visible = True
CadApp.WindowState = acMax
Set CadDoc = CadApp.ActiveDocument
CadDoc.Utility.Prompt "Hello from Access, the time is: " & TheTime
Set CadApp = Nothing
End Sub
I have no idea where to go from here. What are the commands to control the sheet set manager and change data, and can the .dst file be edited without even opening up autocad? is there a list of all available autocad vba commands and functions?
If you are declaring CadApp as AcadApplication you must have added a reference to AutoCAD.
That means you should be able to see the object model using your Object Browser in your VBA IDE. No?
There is also a very helpful site www.theswamp.org which has a whole section devoted to AutoCAD VBA.
If I understand your question correctly, you want to automate filling attributes in a drawing title blocks (such as title, drawer, part number, etc) right from MS Access.
Your code can access the Autocad command line already, but Autocad doesn't seem to have the exact command for filling drawing attribute. (command list)
So looks like you need to fill the attributes programatically using the COM API.
The following question appears to be relevant with yours and the accepted answers does provide a sample code:
Is it possible to edit block attributes in AutoCAD using Autodesk.AutoCAD.Interop?
Note that in that question the asker was developing a standalone application in C# .NET, where as you will be using VB Automation from MS Access. Shouldn't be too different since the Component Object Model (COM) being used is the same.
What are the commands to control the sheet set manager and change data and can the .dst file be edited without even opening up autocad?
(sorry can't post more than 2 links)
docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/files/WS1a9193826455f5ffa23ce210c4a30acaf-7470.htm
No mention about data change, though.
is there a list of all available autocad vba commands and functions?
Yes.
%ProgramFiles%\Common Files\Autodesk Shared\acad_aag.chm - Developer's Guide
%ProgramFiles%\Common Files\Autodesk Shared\acadauto.chm - Reference Guide
Online version:
help.autodesk.com/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-36BF58F3-537D-4B59-BEFE-2D0FEF5A4443.htm
help.autodesk.com/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-5D302758-ED3F-4062-A254-FB57BAB01C44.htm
More references here:
http://usa.autodesk.com/adsk/servlet/index?id=1911627&siteID=123112
:) Half the way gone ;)
If you has a open autocad with a loaded drawing you can access the whole thing directly.
Sub block_set_attribute(blo As AcadBlockReference, tagname, tagvalue)
Dim ATTLIST As Variant
If blo Is Nothing Then Exit Sub
If blo.hasattributes Then
tagname = Trim(UCase(tagname))
ATTLIST = blo.GetAttributes
For i = LBound(ATTLIST) To UBound(ATTLIST)
If UCase(ATTLIST(i).TAGSTRING) = tagname Or UCase(Trim(ATTLIST(i).TAGSTRING)) = tagname & "_001" Then
'On Error Resume Next
ATTLIST(i).textString = "" & tagvalue
Exit Sub
End If
Next
End If
End Sub
Sub findtitleblock(TITLEBLOCKNAME As String, attributename As String,
attributevalue As String)
Dim entity As AcadEntity
Dim block As acadblcck
Dim blockref As AcadBlockReference
For Each block In ThisDrawing.BLOCKS
For Each entity In block
If InStr(LCase(entity.objectname), "blockref") > 0 Then
Set blockref = entity
If blockref.effectivename = TITLEBLOCKNAME Then
Call block_set_attribute(blockref, attributename, attributevalue)
exit for
End If
End If
End If
Next
Next
End Sub
call findtitleblock("HEADER","TITLE","Bridge column AXIS A_A")
So assume you has a title block which has the attribute TITLE then it will set the Attribute to the drawing name. it mioght also possible you has to replace the thisdrawing. with your Caddoc. I usually control Access and Excel form autocad and not vice versa ;)
consider also to use "REGEN" and "ATTSYNC" if "nothing happens"
thisdrawing.sendcommens("_attsync" 6 vblf )