Access/Excel: Method End of object Range failed? - vba

I have an Access db that processes and imports Excel workbooks. It has historically worked well, but is suddenly giving me this error on all workbooks - even ones that previously worked:
-2147417851: Method 'End' of object 'Range' failed
The line causing the problem is:
iLastCBRow = XlBook.Worksheets("4_CensusBlocks").Range("B16001").End(xlUp).Row
If I step through this line in the Immediate window and enter
XlBook.Worksheets("4_CensusBlocks").Range("B16001").Value
it returns the value of that cell correctly.
I thought that the Access db might be corrupt, so I recreated it. Same problem. I also manually forced a repair on the Excel workbook. I even uninstalled and reinstalled Office.
Running Office 2016 64 bit now on Windows 7.
Does anyone have an idea what the problem might be? Thanks

it looks like it is because you have more than 16001 lines in the file. The first command
iLastCBRow = XlBook.Worksheets("4_CensusBlocks").Range("B16001").End(xlUp).Row)
sets iLastCBRow to the starting row.
Try using
iLastCBRow = ActiveSheet.UsedRange.SpecialCells(xlLastCell).Row
instead

I still don't understand WHY, but the problem seems to have been in using early binding of Excel object variables. Once I put in place
dim xl as object
dim xlbook as object
set xl = createobject("Excel.Application")
set xlbook = xl.workbooks.open(filename)
Instead of just
dim xlbook as excel.workbook
set xlbook = getobject(filename)
The error went away. I have only had Office 2016 installed this whole time, so perhaps an update made the OLE server think that I had multiple Offices installed or something?? No idea.

Related

MS Access Compile Error opening excel application [duplicate]

This question already has answers here:
How to fix Compile Error: User-defined type not defined when using Excel VBA from Outlook?
(2 answers)
Closed 5 days ago.
I am trying to write a simple onclick button to open an excel file that already exists on my desktop
what i dont understand is I am using the same Dim as many other examples I have seen. but I am getting a Compile Error "User defined type not defined" and it pulls up the code showing blue highlights Dim excelapp As Excel.Application but Yellow highlight on Private Sub line. Where am i going wrong. is the failure actually further down the code? I ma running Access 365 and Should i be using a different syntax to reference Excel?
Private Sub cmdcopyfieldsonly_Click()
Dim excelapp As Excel.Application
Dim wbTarget As Excel.Workbooks
Dim qdfquerytest As QueryDef
Dim rsquerytest As Recordset
Set qdfquerytest = CurrentDb.QueryDefs("OpenComplaintsQuery")
Set rsquerytest = qdfquerytest.OpenRecordset()
Set excelapp = CreateObject("Excel.Application")
excelapp.Visible = True
Set wbTarget = Excel.Workbooks.Open("C:\Desktop\copytest.xlsx")
wbTarget.worksheets("Sheet1").Range("B8").Value = rsquerytest(2).Value
End Sub
It's a matter of early vs late binding, which are mixed in your code.
Early Binding.
Early binding requires a hard reference of the type e.g. Excel, so VBA has information about the type during compilation. You can then declare the variable by its type and also have intellisense while typing.
Dim app As Excel.Application
Set app = New Excel.Application
The drawback is when changing office versions as the code still references the old version - the reference will need to be updated.
Late Binding
Late binding does not require a hard reference since the variable is declared using the base type of Object and gets resolved at runtime. No issues when changing office version but you lose intellisense.
Dim app As Object
Set app = CreateObject("Excel.Application")
In you case, this is absolutely valid when using late binding:
With CreateObject("Excel.Application")
With .Workbooks.Open("C:\Desktop\copytest.xlsx")
.Worksheets("Sheet1").Range("B8").Value = rsquerytest(2).Value
End With
End With

VBA : Enexpected running VBA from cmd line

I wanted to open an existing ppt using Wscript and modify it. For that I am opening the file in visual studio editor and executing the script from cmd in windows using WScript hi.vbs
But when I ran the same code I am getting error.
Expected end of statement in line 4
Line 4 looks like Dim objNewPowerPoint As Object
However Same case works when I run code in excel VBA editor.
When I am removing the As object I am not getting any error nor any changes are happening in the PPT file.
Wondering what is the possible issue.
I am not using excel vba or word vba i am just running the file from cmd
Sub Open_an_existing_Presentations()
Dim objNewPowerPoint As Object
Dim MyPresentation As Object
Dim pSlides As Object
Set objNewPowerPoint = CreateObject(PowerPoint.Application)
'Make this Application Object Visible
objNewPowerPoint.Visible = True
Please help me how can i modify and more importantly how to see both errors compile and syntax.
FYI : I am completely new into VBA and I am trying to update a PPT and wanted to run vba script from another program so trying something like this. Best suggestions are always welcome
In VBScript you cannot dim something as something.
Dim objNewPowerPoint
Dim MyPresentation
Dim pSlides
And dim is optional and serves no technical purpose in VBS (it merely catches spelling mistakes if Option Explicit is specified, else it does nothing at all as in your case except take time to the process the line). In compiled languages it allocates storage and checks data types when using it.
When you use Set = VBS knows it an object and makes it one (4 x 32 bit integers - One a reference count and another a memory address of the function table for the object - two are unused). If you use x=5555 vbs knows it's a integer.

Creating and Accessing a OLEObject

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

Why doesn't code work in VB.net, but works in VBA; GetObject

VBA code works great:
Sub testVBA()
Dim wb As Object ' Lotus123.Document
Set wb = GetObject("S:\Temp\T\0375D.WK3", "Lotus123.Workbook")
End Sub
VB.net code fails:
Sub TestVBNet()
Dim wb As Object ' Lotus123.Document
wb = GetObject("S:\Temp\T\0375D.WK3", "Lotus123.Workbook")
End Sub
In VB.net I get a FileNotFoundException: "File name or class name not found during Automation operation."
As I can run it from VBA that means the file exists and that the class name exists. So why doesn't it work and how can I fix it in VB.net.
EDIT: I guess I'm not sure how to start diagnosing this: Obviously the class exists on my computer but somehow VB.net doesn't manage to find it. Maybe VB.net uses a different method to activate the class. Maybe a registry entry is missing. I am glad for any suggestions.
Edit 2: I also tried using CreateObject and got this error: "Cannot create ActiveX component." Not unexpected.
For some reason VB.net cannot find the class name "Lotus123.Workbook" so I tried getting the file without the class name and it works fine in XP.
Dim wb As Object ' Lotus123.Document
wb = GetObject("S:\Temp\T\0375D.WK3")
EDIT: In Win8 64bit the above doesn't work; just hangs.
The code below works in XP 32 bit as well as in Win8 64 bit. I checked with process monitor what is happening under the hood. CreateObject checks for the CLSID in the registry using the given object. Then it looks up the necessary info using the CLSID.
Public Shared Function GetLotusWB(ByVal sFile As String) As Object
'HKCU takes precedence if exists
'HKCU\Software\Classes\Lotus123.Workbook\CLSID
'HKCU\Software\Classes\CLSID\{29130007-2EED-1069-BF5D-00DD011186B7}
'normally this is used because Lotus123 doesn't create HKCU entries
'HKCR\Lotus123.Workbook\CLSID = {29130007-2EED-1069-BF5D-00DD011186B7}
'HKCR\CLSID\{29130007-2EED-1069-BF5D-00DD011186B7}\InprocHandler32 = ole32.dll
'HKCR\CLSID\{29130007-2EED-1069-BF5D-00DD011186B7}\LocalServer32 = C:\Lotus\123\123w.exe
'using object as that sometimes works better
Dim LotusObj As Object = CreateObject("Lotus123.Workbook")
'get application
'need a reference to Lotus 123 else declare as Object
Dim LotusApp As Lotus123.Application = LotusObj.Application
'FAILS: LotusApp.Visible = True
'open file; also works fine As Lotus123.Document
Dim ldoc As Object = LotusApp.OpenDocument(sFile)
'visible and activate (must declare as Object else gives exception)
Dim appObject As Object = ldoc.Application
appObject.Visible = True
ldoc.Activate()
Return ldoc
End Function
This works great because it creates the "Lotus123.Workbook" which is used to get the application object.
Load the file into an Excel workbook. It should be able to convert the lotus123 workbook on the fly.
First of all, check to make sure your inclusions (I think under Tools menu, includes or references or something like that) include the library that references Lotus123.Document. Chances are it's in the "Microsoft Excel 14.0 Object Library" or similar.
I've heard it said that VB is not VBA!

vbScript opens up excel but doesn't load macro/modules?

I m in a very weird situation. I created a vbs script that would open my excel file. I had defined vba code in WorkBook_open method. I thought creating a vbs script to open up my excel would invoke my workBook_open method and execute the vba code inside it. But I was wrong. Below is my vbs code.
filePath = "E:\data_extracts\mydata.xlsm"
Set oExcel = CreateObject("Excel.Application")
oExcel.Workbooks.Open(filepath)
oExcel.Visible = True
oExcel.Run "RefreshDataFromIQY"
oExcel.ActiveWorkbook.Save
oExcel.ActiveWorkbook.Close
oExcel.Quit
Set oExcel = Nothing
On debugging, it fails at oExcel.Run "RefreshDataFromIQY" saying either macros are not available or disabled. Hence it is the code just opnes up excel application successfully and that's all it does. I have macro codes in module1, module2. How/where do I write to execute my macros in vbs script below. My macros/modules have to be executed in sequence and some of my macros are recorded macros. Any help is much appreciated. Thanks.
Thanks for your input Scott. Here's what I made changes to my code
Dim oExcelApp
Dim oExcelWkb
set oExcelApp = createobject("Excel.Application")
set oExcelWkb = oExcelApp.Workbooks.Open("\\myserver\data_extracts\TestTOPTMay307.xlsm")
oExcelWkb.Close True
oExcelApp.Quit
However on running it from command line, its giving me runtime error Object required: 'Close'. Any idea why? Why is it failing to Close? What am i doing wrong? Thanks.
I just tested your code against a dummy file I made. It worked when I placed the code inside a module and left it as public. However, when I put into a private module -> like worksheet level module, I got the error you got.
However, when I referenced the private object, the code ran through. So my answer to you is to replace
oExcel.Run "RefreshDataFromIQY"
With
oExcel.Run "[yourClassName].RefreshDataFromIQY"
Also, I placed a workbook_event in my file as well. The event triggered successfully on open, so if there is trouble with yours, it's most likely in the code inside the event.