Defining a variable as a range - VB.NET - 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.

Related

Get Word bookmark index to replace image inside bookmark from Excel

This question is related with a previous one.
I have an open Word document with a bunch of bookmarks, each with an inline image of an Excel table previously exported from Excel.
Now, I need to update the tables in the Word document as they have changed in Excel.
The way I'm doing this is matching the table names in Excel with the bookmark names in Word. If they are equal than I want to replace the existing images in Word by the current ones.
This is my code so far:
Option Explicit
Sub substituir()
Dim Mark As String
Dim Rng As Range
Dim ShpRng As Range
Dim WordApp As Object
Dim DocumentoDestino As Object
Dim folha As Worksheet
Dim tabela As ListObject
Dim nomeTabela As String
Set WordApp = GetObject(class:="Word.Application")
Set DocumentoDestino = WordApp.ActiveDocument
For Each folha In ThisWorkbook.Worksheets
If folha.Visible Then
'loop all excel tables
For Each tabela In folha.ListObjects
tabela.Name = Replace(tabela.Name, " ", "")
Mark = CStr(tabela.Name)
With ActiveDocument
If .Bookmarks.Exists(Mark) Then
Set Rng = .Bookmarks(Mark).Range ' returns runtime error 13: Type mismatch, I guess it is because .Bookmarks expects the bookmark index instead of the name.
If Rng.InlineShapes.Count Then
Set ShpRng = Rng.InlineShapes(1).Range
With ShpRng
Debug.Print .Start, .End
ShpRng.Delete
End With
End If
End If
End With
Next tabela
End If
Next folha
End Sub
The code seems ok, except for the line marked above that returns runtime error 13, is there any way to get to the bookmark index instead of the name or another way to fix the issue?
Thanks in advance!
The problem is from the Range object. There is such an object in Excel as well as in Word. Since you are running Excel, both Rng and ShpRng are declared as Excel ranges implicitly. Declare them as Word.Range.
Quite generally, be more careful with your use of variables. You perfectly declared Set DocumentoDestino = WordApp.ActiveDocument, but then you proceed with
With ActiveDocument
If .Bookmarks.Exists(Mark) Then
In Excel, there is no ActiveDocument. Perhaps that is why Excel correctly divines your intention to refer to DocumentoDestino. However, if you don't keep tight control instances are likely to arise - whenever you least expect them, of course - when Excel makes the wrong guess.

VBA - Changing Reference document in named formula

EDIT: I wanted to clarify my earlier question. I have existing name formula in my name manager. I would like to set these variables listed below to reference different columns from another document. These variables are referenced in my other spreadsheet.
My question is
1) How do I set the variables to reference another document's column?
2) How can I make it so the Macro allows me to choose which document each time?
Here's my code
Sub UpdateReport()
Dim wbk As Workbook
Set wbk = Workbooks.Open("U:\user\Destination.xls")
Dim x As Variant
Dim FY123 As Range
Dim FY134 As Range
Dim FY145 As Range
Dim FY156 As Range
Dim FY167 As Range
Dim FINCC As Range
Set FINCC = wbk.Worksheets("Worksheet2").Column("D")
Set FY123 = wbk.Worksheets("Worksheet2").Columns("N")
Set FY134 = wbk.Worksheets("Worksheet2").Columns("O")
Set FY145 = wbk.Worksheets("Worksheet2").Columns("P")
Set FY156 = wbk.Worksheets("Worksheet2").Columns("Q")
Set FY167 = wbk.Worksheets("Worksheet2").Columns("R")
End Sub
Thanks,
GS
EDIT: Clarified question

Set xWorkb = New workbook not working, ActiveX error

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.

Copy VBA code from one Worksheet to another using VBA code

Ok here is what I want to accomplish: I am trying to copy all the VBA code from "Sheet2" to "Sheet 3" code pane. I'm NOT referring to copying a Module from one to another but the excel sheet object code.
I already added a Reference to MS VB for Applications Extensibility 5.3
I'm not sure where to start but this is what I have started with and its not going anywhere and probably all wrong. Please Help - Simply want to programmatically copy sheet vba code to another sheet vba pane.
Dim CodeCopy As VBIDE.CodePane
Set CodeCopy = ActiveWorkbook.VBProject.VBComponents("Sheet2").VBE
ActiveWorkbook.VBProject.VBComponenets("Sheet3").CodeModule = CodeCopy
Use the CodeModule object instead of the CodePane, then you can create a second variable to represent the destination module (where you will "paste" the code).
Sub test()
Dim CodeCopy As VBIDE.CodeModule
Dim CodePaste As VBIDE.CodeModule
Dim numLines As Integer
Set CodeCopy = ActiveWorkbook.VBProject.VBComponents("Sheet2").CodeModule
Set CodePaste = ActiveWorkbook.VBProject.VBComponents("Sheet3").CodeModule
numLines = CodeCopy.CountOfLines
'Use this line to erase all code that might already be in sheet3:
'If CodePaste.CountOfLines > 1 Then CodePaste.DeleteLines 1, CodePaste.CountOfLines
CodePaste.AddFromString CodeCopy.Lines(1, numLines)
End Sub
In addition to adding a reference to "Reference to MS VB for Applications Extensibility 5.3"
You'll also need to enable programmatic access to the VBA Project.
In Excel 2007+, click the Developer item on the main Ribbon and then
click the Macro Security item in the Code panel. In that dialog,
choose Macro Settings and check the Trust access to the VBA project
object model.
Thank you all! After testing multiple suggestions above, where "b" is the Worksheet name, you must use .CodeName, NOT .Name
Set CodePaste = ActiveWorkbook.VBProject.VBComponents(WorkShe‌ets(b).CodeName).Cod‌​eModule
If you have set your target worksheet as an object:
Dim T As Worksheet
Set T = Worksheets("Test")
Then you simply need:
Set CodePaste = ActiveWorkbook.VBProject.VBComponents(Worksheets(T.Name).CodeName).Cod‌​eModule

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.