Set xWorkb = New workbook not working, ActiveX error - vba

I have some code below, It works like a charm but I'm curious about some things.
Why can't I make a Set xWorkb = new Workbook statement? Instead I use the Dim xWorkb as new Workbook, which works. But I've learned (hopefully correct) that using the new statement within a Dim is bad practice, and that you should create the object seperately. So why doesn't it work? I get a ActiveX component can't create object error, but the xWorkb is still being created later as an object right due to the new statement in the Dim section? Makes me confusing.
Why can't I use the excel.application.workbooks when defining variable xApp? Is it because I have to specify a workbook and can't just leave the workbooks empty like that? I get a type mismatch error when I'm trying to change excel.application to excel.application.workbooks.
Sub tester()
Dim xWorkb As New Workbook
Dim xApp As Excel.Application: Set xApp = New Excel.Application
Dim xFiles_target() As Variant
Dim file_path As String
xFiles_target = Array("Bella.xls", "Fizz.xls", "Milo.xls", "Jake.xls")
file_path = Dir("C:\Users\hans\Desktop\")
Do While Len(file_path) > 0
Debug.Print file_path
If UBound(Filter(xFiles_target, file_path)) >= 0 Then
Debug.Print "found " & file_path
Set xWorkb = xApp.Workbooks.Open("C:\Users\hans\Desktop\" & file_path)
xApp.ActiveSheet.Cells(2, 2) = "tester"
xWorkb.Save
xWorkb.Close
End If
file_path = Dir
Loop
End Sub

You cannot create new workbooks with New because workbooks are coupled with Application and must be created with Workbooks.Add or Workbooks.Open.
Dim xWorkb as new Workbook does not work - it appears to work because you don't access xWorkb between declaring it and assigning it with Workbooks.Open. If you did, you would get the same ActiveX component can't create object error.
The error is because Excel.Workbook does not have any public constructors.
You cannot define a variable as excel.application.workbooks because that is not a type. It is a property named Workbooks, of type Excel.Workbooks, that belongs to an object named Application of type Excel.Application.
You can declare the variable as Excel.Workbooks, but you probably don't want to, because you will need to create an Excel.Application to use it anyway.

Related

Can GetObject do this?

I'm currently working on developing a macro that will input various forms into an access database.
Due to the nature of the beast of this program, I've had to split my main program into two sub programs and call them, but I need to use getobject to call a file path twice now.
I use getobject to open a file, and then use myrec.fields(~column name~) = xlsht.cells(1, "a") to populate various column values. I'm unsure if there are other "efficient" ways to accomplish this.
I was wondering if it is possible to use a variable in place of the filepath with the GetObject command, instead of needing to manually replace the file path in the code.
I've tested a fair amount of different code, including the path, class functionality but I don't think I understand VBA enough to truly make the best use of that.
I can make it work using this
Dim XL As Variant
Dim XLApp As Variant
Dim XLsht As Variant
Dim XLwrkbk As Variant
Set XL = CreateObject("Excel.Application")
Set XLwrkbk = GetObject(~file path~)
Set XLsht = XLwrkbk.Worksheets(1)
Set MyRec = CurrentDb.OpenRecordset("database name")
Ideally I would like it to be
Dim filename As String
Dim XL As Variant
Dim XLApp As Variant
Dim XLsht As Variant
Dim XLwrkbk As Variant
filename = " ~insert file path~ "
Set XL = CreateObject("Excel.Application")
Set XLwrkbk = GetObject(filename)
Set XLsht = XLwrkbk.Worksheets(1)
Set MyRec = CurrentDb.OpenRecordset("database name")
I receive a run time error
Run-time error '5':
Invalid procedure call or argument.
Try something like this:
Dim XL As New Excel.Application, Filename As String
Filename = "~ your file ~"
XL.Workbooks.Open (Filename)
myrec.fields(~column name~) = XL.Worksheets(1).Range("A1").value

Defining a variable as a range - VB.NET

I think I'm losing my mind - how do you declare a variable as a string and then set it equal to a range in an Excel workbook in VB.NET? In VBA this was easy:
Dim SQL as string
SQL = ActiveWorkbook.Sheets("MySheet").Range("SQL")
If I try do something like this in VB.NET (in Visual Studio 2015), first I can't find Activeworkbook. Second, if I try Excel.Range("SQL"), I get an error saying that 'Range' is an interface type and cannot be used as an expression. Also, it doesn't look like the Range data type exists either. Surely this functionality exists in VB.NET, right?
Thanks for the help!
To work on Excel since VB.NET, first you must add the reference to your Project :
Microsoft.Office.Interop
To Add a Reference :
In Solution Explorer, right-click on the References node and choose Add Reference.
Import the Reference in your code :
Imports Microsoft.Office.Interop
Try to use this code :
Dim AppExcel As New Excel.Application 'Create a new Excel Application
Dim workbook As Excel.Workbook = AppExcel.Workbooks.Add() 'Create a new workbook
Dim sheet As Excel.Worksheet = workbook.Sheets("Sheet1") ' Create variable a Sheet, Sheet1 must be in WorkBook
'Work with range
Dim cellRange1 As Excel.Range = sheet.Range("A1") 'Range with text address
cellRange1.Value = "Text in Cell A1"
Dim cellRange2 As Excel.Range = sheet.Cells(2, 2) 'Range("B2:B2") with index; Cells(N°Row,N°Col)
cellRange2.Value = "Text in Cell B2"
Dim tableRange3 As Excel.Range = sheet.Range("A1:F4") 'Range with text address
Dim tableRange4 As Excel.Range = sheet.Range(sheet.Cells(1, 1), sheet.Cells(4, 6)) 'Range("A1:F4") with index; Cells(N°Row,N°Col)
AppExcel.Visible = True 'To display the workbook
Code without variable sheet
Dim AppExcel as New Excel.Application
Dim workbook As Excel.Workbook = AppExcel.Workbooks.Add()
'Range
Dim cellrange1 as Excel.Range = AppExcel.ActiveWorkbook.Sheets("Feuil1").Range("A1")
You would need to start from your application object. Suppose that's AppExcel:
Dim AppExcel As New Excel.Application
From there, you could do:
Dim cellrange1 as Excel.Range = AppExcel.ActiveWorkbook.Sheets("MySheet").Range("SQL")
Because you've declared cellrange1 as a Range it can't be set to Range("SQL").Value.
Value returns an object which is the value contained in that Range.
That's so wordy. To put it (maybe) more clearly, Range("SQL") returns a Range. Range("SQL").Value returns an object.
If you want to get the value, that would be cellrange1.Value, or perhaps cellrange1.Text. Assuming that the range contains some sort of SQL, I'd go with Text.
An unfortunate aspect of Excel interop programming is that many properties return objects rather than strongly-typed values. For example, the object returned by Range.Text is always going to be a string, but the property still returns an object. That means that Visual Studio intellisense will often not tell you what type a property returns. You'll need to look up properties and functions in the documentation to really know what they return.

What does the keyword 'New' do in VBA?

In VBA procedures we are constantly meeting the keyword New usually on instantiation of an object reference to an existing object instance. But in some instantiations we use the keyword New while in others we don't for example:
Dim T As Excel.Workbook
Set T = Application.Workbooks(Bk)
In the upper example No.1 the "New" keyword has not been used
Dim fso As FileSystemObject
Set fso = New FileSystemObject
In the upper example No.2 the New keyword is being used
Why that? Keep in mind i'm fresh of the boat in VBA but i will do my best to understand!
In addition to that i also get confused when is used/not-used in declaring an object reference for example:
Dim WS As Worksheet
In the upper example No.1 the "New" keyword has not been used
Dim myClassModule As New cl_ChartEvents
In the upper example No.2 the New keyword is being used
The Microsoft Help just tells me nothing...
Keyword that enables implicit creation of an object. If you use New when declaring the object variable, a new instance of the object is created on first reference to it, so you don't have to use the Set statement to assign the object reference.
Gratz2u
Dear people just a last dust-off for deep understanding
Dim WS as Worksheet
Set WS = Worksheets("Sheet1")
Right here we are creating an object that already existed in order to open MS Excel (lets say for examples sake in "default mode") of course which is Sheet1. Since it exists and the New keyword is out of the question how could we instantiate this object in one line right away?
4 #exantas
Sorry says not enough rep to post pic :-(
When you Dim a variable you are specifying what data type it will hold. At the time of creation, its value is always Nothing until you initialize it. Set T = Application.Workbook(Bk) initializes the T variable to the specific instance of Application.Workbook, in this case 'Bk'.
When you Dim fso as FileSystemObject, you are basically saying that fso will hold, at some point, a FileSystemObject; however its initial value is Nothing until you initialize it using Set fso = New FileSystemObject. The New keyword implies you're creating a new object instead of initializing the variable with an existing object as you do with Set T = Application.Workbook(Bk)
Also note that Set fso = FileSystemObject would be invalid because it doesn't know what instance of FileSystemObject you wish to assign to it. This is why you use the New keyword to create a new instance of FileSystemObject.
As stated before, Dim WS As Worksheet merely tells the compiler that you want variable WS to hold a Worksheet object. Since nothing else is specified, at the point of Dim, WS is set to Nothing
Dim myClassModule As New cl_ChartEvents is equivalent to doing:
Dim myClassModule as cl_ChartEvents
Set myClassModule = New cl_ChartEvents
... except on one line of code instead of two. This differs from Dim WS As Worksheet in that the variable is initialized straight away, i.e. myClassModule is set to a new instance of cl_ChartEvents instead of Nothing.
Hope this helps!
You said: "[We are] meeting the keyword New usually on instantiation of an object reference to an existing object instance". Exactly the opposite is true: New is used when something does not exist yet and you want to create it, well "new".
You can omit the New keyword if something already exists, e.g. the Application object, ActiveWorkbook object and others in VBA, that is everything which was already opened by you when starting Excel.
Dim ... As New ... is a shortcut for
Dim ... As ...
Set ... = New ...
For your last question to create a new worksheet, it's done by
Dim WS As Worksheet
Set WS = Sheets.Add
WS.Name = "My new worksheet"
You cannot use Dim WS as New Worksheet, because Microsoft prevents you from doing so. Even if you specify New in that instruction, the object is still Nothing.

'DBNull' Error when attempting to set a range in VB.net. Database is Excel

I've written a pretty useful macro within Excel in VBA and am attempting to transfer it to a stand-alone windows application written in VB.net. I've found all the referencing pretty confusing and am now facing trouble in converting the general syntax of my code.
I'm pasting below the relevant code:
Dim ElevenSheets As Excel.Worksheet
Dim TwelveSheets As Excel.Worksheet
Dim ThirteenSheets As Excel.Worksheet
Dim WorkingSheet As Excel.Worksheet
Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
xlApp = New Excel.Application
xlWorkBook = xlApp.Workbooks.Open("FILENAME.xls") 'Removed file name for company confidentiality purposes.
ElevenSheets = xlWorkBook.Worksheets("2011")
TwelveSheets = xlWorkBook.Worksheets("2012")
ThirteenSheets = xlWorkBook.Worksheets("2013")
WorkingSheet = xlWorkBook.Worksheets("WorkingSheet")
...
Cell = WorkingSheet.Range("B3") '<--- This line causes the error.
CurrentCell = (Cell.Row & "," & Cell.Column)
CurrentRow = Cell.Row
MyColumn = (Cell.Column)
CurrentCell = (CurrentRow & "," & MyColumn)
So, as you can see I've pointed out the line that gives me an error. I'm trying to set a range names "Cell" and the error "MissingMemberException unhandled No default member found for type 'DBNull'" presents itself.
Does anyone know what I've done wrong? I'm sure it's something very simple with my syntax but am finding this whole process difficult and also finding it difficult to understand other reasonably similar topics on the internet.
Thanks for bothering to ready this and let me know if you need more context,
Josh
I dont see any constructor for Cell. Also you dont have to explicitly declare all those worksheets. You can simply call them using something like xlWorkBook("WorkingSheet").Range("B3")
I have fixed the problem through trial and error. The way I did it was simply change these declarations:
ElevenSheets = xlWorkBook.Worksheets("2011")
TwelveSheets = xlWorkBook.Worksheets("2012")
ThirteenSheets = xlWorkBook.Worksheets("2013")
WorkingSheet = xlWorkBook.Worksheets("WorkingSheet")
To this:
ElevenSheets = CType(xlWorkBook.Worksheets(1), Excel.Worksheet)
TwelveSheets = CType(xlWorkBook.Worksheets(2), Excel.Worksheet)
ThirteenSheets = CType(xlWorkBook.Worksheets(3), Excel.Worksheet)
WorkingSheet = CType(xlWorkBook.Worksheets(4), Excel.Worksheet)
I don't know whether changing the sheet names to the sheet number fixed it or the CType fixed it. But one of them did.
Thank-you for your contributions!

Using a Variable to Dim a Worksheet

I have a sheet with one cell that is = the name of a folder that I want to dim as a variable. what I want to do is set that cell = the filename variable. It will probably be easier to look at my code. I am currently getting the "object required error on my "set Input 1" and my way to set the variable is presumably wrong as well
Dim WbkA As Workbook
Dim Input1 as string
Set Input1 = Workbooks.Open(Filename:="G:\Reporting\ReportCompare.xls").worksheets("Sheet4").Range("A4").Value
Set wbkA = Workbooks.Open(FileName:"Input1")
You try to assign a reference of an object with the keyword Set to a data type (String).
Remove the keyword Set and it's gonna be okay.
The code needs to be reordered slightly in order to breakout the steps.
Get the file path and name from the workbook and store it as a string
variable (Input1).
Open the file using the value stored in the string variable (Input1).
Set a reference to the open file as an object variable (WbkA).
Listed below is the code
Sub test()
Dim Input1 As String
Dim WbkA As Workbook
Input1 = Worksheets("Sheet4").Range("A4").Value 'Get the path and file name
Workbooks.Open Filename:=Input1 'Open the file
Set WbkA = ActiveWorkbook 'Set the reference to the workbook
MsgBox WbkA.Name 'Show the name value from the object.
End Sub