How do you retrieve a pointer to the active workbook In a vb .net excel document customization (not add in) - vb.net

I am new to VB.net and am moving an app from VBA. I want to use the document customization model, but can't for the life of me find a way to retreive a pointer to the workbook that is hosting the customization. I have tried
dim wb as workbook = Me.Workbook
dim wb as workbook = thisWorkBook
dim wb as workbook = ThisApplication.workbook
etc. I only need this in order to be able to select worksheets in the customization so if there is anotherway to do that then that would answer my question too. For example I want to execute this to get a handle to a specific worksheet.
dim ws as worksheet = wb.sheets("My Sheet Name")
Apologies for what is clearly a very basic question but I have googled around for about three hours so far with no luck.

After a lot of additional trial and error I came across this solution.
You can access the application workbook through the Globals variable produced by VSTO. Thus,outside of the class declaration for thisWorkbook -- the following will work:
Dim wb as ThisWorkBook
wb = Globals.ThisWorkbook
Note that web is not of type Workbook but ThisWorkBook which is an overloaded class defined by Visual Studio in the document customization template.

Related

Open and update an existing workbook with 2 worksheets

This may be simplistic to most of you. I just started using VBA to create and update excel workbooks. I found some code on the internet to open and update an existing workbook and worksheet. Like I said, I am brand new at this. Does this code even make sense? I just need to know how to open an existing workbook and all the examples I have found aren't working in our environment.Thanks for any help I can get
Dim wbSource, xlApp, srcWorksheet
'initialize
Set xlApp = CreateObject("Excel.Application")
'open source and target files
Set wbSource = lApp.Workbooks.Open("X:\GCIXCycleCompare_test_auto.xlsx")
set srcWorksheet = wbSource.Worksheets("NewCycle")
srcWorksheet.sheets("NewCycle").Activate
srcWorksheet.Rows("1:1").Delete
If you are in Excel VBA, this isn't quite what you want. This code was written for an external app (say written in VB6) to open Excel remotely and then do stuff to that copy of Excel. If you are already in Excel/VBA you obviously don't need to do that.
In VBA, the equivalent code would be something like this:
Public Sub MyCode()
Dim wb as Workbook
Dim ws as Worksheet
Set wb = Application.Workbooks.Open("X:\GCIXCycleCompare_test_auto.xlsx")
Set ws = wb.Worksheets("NewCycle")
ws.Rows(1).Delete
End Sub
If you run this code (by click F5 from inside VBA ... or by run macro in Excel) it should open up the test file off the X: drive, and then delete the first row of it.

VBA: How to address the correct workbook when giving a worksheet as an argument to a function?

I have a question regarding the correct address of Workbooks in VBA, which I am fairly new to.
Here is what I have done so far:
I have written a sub that, amongst other things, creates a worksheet with the CodeName "table10".
Then I defined a function to manipulate the contents of said sheet: this function
Text_To_Numbers(worksheet as worksheet)
expects a worksheet argument. I call the function from another sub using the following line:
Call Text_To_Numbers(table10)
Now, here is my issue:
The above works flawlessly when the only open workbook is the one I want to manipulate with my function. However, when I have multiple open workbooks, the function will try to manipulate a different workbook, resulting in an error.
I am quite certain that there must be a way to specify the workbook to be used, but I am unable to find it. That being said, there is another complication: The name of the workbook which I would like to manipulate is machine generated, so it always has a different name. This means that using an explicit reference to the same file name time and again is not an option.
Could anybody help me resolve this?
You need to fully qualify objects in VBA to avoid situations like this where it is ambiguous what the parent is.
In your situation, you want the sheet to be connected to its parent workbook, so make sure you specify that it came from a given workbook!
You cannot directly refer to worksheets in other workbooks by their CodeName, this can only be done to the ThisWorkbook object (the workbook containing the VBA code). See the question Fully reference a worksheet by codename for details on how to get the sheet by its codename from another workbook. I have included the function in the answer and how to use it in this context.
You created the sheet table10 in one of the following:
ActiveWorkbook
ThisWorkbook
WB (some workbook object)
So you can access it using that workbook object without a need for the name!
Using ThisWorkbook.table10 should give same behaviour as just table10, but here are two neater examples for calling the function.
' A neater way to call the function:
Text_To_Numbers worksheet:=ThisWorkbook.table10
' You could also call it simply using
Text_To_Numbers ThisWorkbook.table10
If your sheet is not within ThisWorkbook
' Get sheet (from the workbook object you are using, WB) and pass to your Text_To_Numbers
Text_To_Numbers GetSheetWithCodename("table10", WB)
Function GetSheetWithCodename(ByVal worksheetCodename As String, Optional wb As Workbook) As Worksheet
Dim iSheet As Long
If wb Is Nothing Then Set wb = ThisWorkbook ' mimics the default behaviour
For iSheet = 1 To wb.Worksheets.Count
If wb.Worksheets(iSheet).CodeName = worksheetCodename Then
Set GetSheetWithCodename = wb.Worksheets(iSheet)
Exit Function
End If
Next iSheet
End Function
Try assigning the workbook and sheet to a variable then calling it in this way when you need to do some work in it:
Dim WB As Workbook
Dim WS As Worksheet
'If you want to open the workbook before doing work
Set WB = Workbooks.Open("/Workbook path name goes here”)
Set WS = WB.Worksheets("Table‌​10")
Then you just need to pass a call to the WS variable from within your function to perform operations within the specified sheet.
Edit:
Apologies, didn't realise you were trying to reference the index name in the project editor when I first read your question. The code name can be referenced from an external workbook with the following example which shows how to select the workbook and sheet codename to perform a copy/paste from one workbook to another:
Sub UseCodeNameFromOutsideProject()
Dim WS As Worksheet
With Workbooks("MyWorkbook.xlsb")
Set WS = _
.Worksheets(CStr(.VBProject.VBComponents("Sheet1").Properties(7)))
WS.Range("A1").Copy
Selection.Copy
WS.Range("B1").PasteSpecial
End With
End Sub
Thanks to Enderland for the idea.

Copying and pasting between workbooks

So I currently have three workbooks, I have created a folder in my Desktop, and where I am using workbook x, through a range on a cell to open up workbook called m (old) and workbook called n (new). I am then updating the old with the new.
Problem
Once I have opened up m, I am having to do a save as of the file as a newname. I am keen to know is there way of referring to it without using the workbook newname, as this workbook name would be concatenated with today's date and the name can be quite long and time consuming to type. I have produced several subroutines, one to remove protection etc,. and one for carrying out the coping actions and I am calling the subroutines, I just want to now if there is way of linking the newsaved name to some of the subroutines from referencing. Alternatively the old file could be saved at the very end. I am keen to pursue this avenue as I will be playing in certain other cases with four workbooks.
I have taken this code and amended it, but I am unable to open both spreadsheets, the strange thing when i block out the code and go through a test both work for each path they work, but not at the same time.
this is the code i amended, which i was able to find in
Dim x As Workbook, y As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Set x = Workbooks.Open("path to copying book")
Set y = Workbooks.Open("path to pasting book")
Set ws1 = x.Sheets("Sheet you want to copy from")
Set ws2 = y.Sheets("Sheet you want to copy to")
With ws1
.Cells.Copy ws2.cells
y.Close True
x.Close False
End With
End Sub
this is my code where it is not opening both workbooks
Dim wb as Workbook
Dim wb1 As Workbook, wb2 As Workbook
Dim ws as Worksheet, ws1 As Worksheet, ws2 As Worksheet
Dim Lst As Long,
Dim r1, r2 As Range
Set wb = ThisWorkbook
Set wb1 = Workbooks.Open("Sheets("x").Range("A4").Value")
Set wb2 = Workbooks.Open("Sheets("x").Range("A5").Value")
With wb2
Call Wbkunprtect()
I would be grateful for some help, please for those who are trigger happy can you hold back from pressing the down arrow some of us are not excel knowledgeable and also trying to learn and do not want to be banned from asking questions, I am trying to move data between two workbooks wb1 and wb2, through another wb i have completed my code, and this is the bit which stopping me from going forward.
I have learned a great deal from this site the reason I asked certain questions as I am reluctant to use select or activate as I have been told this is a bad habit you have to keep away from.
From what I understood, you'll need to use a WorkBook object! the WorkBook object will have the instance of the newly added workbook. It is as simple as that:
Sub example_new_workbook()
Dim wb As Workbook
Set wb = Workbooks.Add
wb.SaveAs ("path where you want to save")
End Sub
That way, "wb" will have the instance of the new workbook, and you can use freely to reference that new workbook. Remember, the WorkBooks object holds all the instances of all open workbooks, so you can get the reference for any other workbook through this object.
As to make it "Global", you can declare it outside the "Sub" scope, so the variable will be permanent as long as the module (or wherever you put your code) is open like this:
public wb as Workbook
Sub <your_routines>()
...
End Sub

reading excel files in access vba

I am trying to read an excel file inside a access application using VBA. I have this code:
Dim xlApp As Excel.Application
Dim xlWrksht As Excel.worksheet
which I got from here:
Best way to read an Excel file into an Access database
but when I try to run it, I am getting error that user defines type is not define.
Should I add a reference to the application?
Is there any way that can do it without adding a reference to my application?
Edit 1
After adding reference to the code, Now I have this code:
Dim excelApp As Excel.Application
Dim workbook As Excel.workbook
Dim Worksheet As Excel.Worksheet
Set excelApp = CreateObject("Excel.application")
Set workbook = excelApp.Open(InputFileName)
Set Worksheet = workbook.Worksheets(1)
But now I am getting error on line:
Set workbook = excelApp.Open(InputFileName)
as the excelApp doesn't have any method called Open. Should I add any other reference?
If you know the structure of the Excel worksheet, you can link to various ranges in one worksheet, an treat each of them as a table, using queries and/or Recordsets. Last parameter in this line represents a range in the first worksheet:
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel9, myTableName, ExcelFileName, False, "f3:L10"
You remove this link as any table:
CurrentDb.TableDefs.Delete (myTableName)
If you do not add a reference to the objects, then Access will not have knowledge of the objects to use with variables. An object/type is either built-in or referenced so it is usable.
You should also include Excel.Workbook, as the hierarchy is App -> Workbook -> Worksheet -> Cells.
You need to add a reference to your Access project, else it would not recognize it.
G.

VBA Excel Workbooks Object Variable

I am trying to set two workbook variables - here are the first four lines of my code:
Dim wb1 As Workbook
Dim wb2 As Workbook
Set wb1 = Workbooks("C:\Users\ShaneM\Documents\File1.xlsx")
Set wb2 = Workbooks("C:\Users\ShaneM\Documents\Computer Languages\VBA\File2.xlsm")
The error I am getting on line 3 is:
Runtime error 9 - Subscript Out Of Range
The files definitely exist in these locations. Obviously much learning to be done. What am I doing wrong, please?
Thank you.
The .Workbooks() is a collection of workbook objects opened in the current Application object (which you don't write in your code, but it's called by default).
The collection .Workbooks() goes out of range because the workbook is not currently open in your Application; if you want to use your workbook, in fact, what you need to do is opening it into the current Excel Application instance:
Set wb1 = Workbooks.Open("C:\...")
This will though cause the workbook to show up, because you're opening in your current application, and unfortunately is not possible to open it in Visible=False mode. However, you might want to use a new Excel instance set to Visible = False, so you will be able to read the content without actually displaying it. Which means, in code:
Set excObj = CreateObject("Excel.Application")
excObj.Visible = False
Set wb1 = excObj.Workbooks.Open("C:\...")
Please note that I'm specifying to open the workbook with excObj, which is not the current Application but another object of the same type that is intentionally set to Visible = False.
According to https://msdn.microsoft.com/en-us/library/office/ff841074.aspx, the Workbooks collection contains only the currently opened workbooks. The error simply tells you, that the requested workbook is not opened at the moment.
You have to use the method Workbooks.Open:
Set wb1 = Workbooks.Open("C:\Users\ShaneM\Documents\File1.xlsx")
When the Workbook is already opened, you can then use the property Workbooks.Item to get the object (note that you can omit .Item, as it is the default property of the Workbooks collection).
Set wb1 = Workbooks("File1.xlsx")
Also note that the names of opened workbooks must be unique within the same application. I.e. the following will not work:
Set wb1 = Workbooks.Open("C:\Folder1\File.xlsx")
Set wb2 = Workbooks.Open("C:\Folder2\File.xlsx")