I am pretty new to VBA, so please excuse me if this is a simple question! I have created a template report (titled "Client_Name") that I want populated for each client - in essence all this involves is selecting the client in the PivotTable's report filter and copying the PivotTable's data values to the template. In order to automate this, I have created the following code to duplicate the template and rename it for the client currently selected in the PivotTable:
Sheet_Name_To_Create = Sheets("Pivot").Range("B1").Value
Sheets("Client_Name").Select
Sheets("Client_Name").Copy After:=Sheets(Sheets.Count)
Sheets(ActiveSheet.Name).Name = Sheet_Name_To_Create
My next step would be to go back to the PivotTable ("Pivot" worksheet) and copy the data to the newly created client worksheet. However, the worksheet's name will obviously change differ for each client. Is there a way to reference the VBA code to select the worksheet whose name is the same as the client currently shown in the PivotTables's report filter?
Sheets(ActiveSheet.Name) is an inconvenient way of saying ActiveSheet.
Just capture ActiveSheet in a variable after copying.
Dim CopiedSheet as Worksheet
Set CopiedSheet = ActiveSheet
You don't need sheet's name when you have the sheet itself.
Recommended reading: How to avoid using Select in Excel VBA macros
Related
How can I select worksheet in excel using vba even when sheet name and sheet position changed constantly?
I was using sheet index to avoid vba fail to select worksheet after changing the worksheet name, however, if I change relative position of the ws, its index changes.
I noticed that sheet name in vba project browser, there is a item called (name) which is a fixed sheet number (I guess it was named by the sequence that I created the ws.) Is it possible to select ws based on this fixed name?
Thank you
You can use Name in VBE to specify your name for Worksheet. This will allow you to rename your Worksheet in Excel according to your needs.
In VBA you can then use something like:
Option Explicit
Sub Test()
MyWorksheetName.Activate
End Sub
This is where you edit your Name:
So I built this macro workbook that creates a formatted monthly report for me.
How it works is the macro builds the report based on some criteria I define, then it copies the data portion from the worksheet "Slide" and pastes it as values to the next worksheet, "Deliverable", using this code:
Application.Goto (ActiveWorkbook.Sheets("Slide").Range("A1"))
Range("C2", Cells(TableRows, 30)).Select
Selection.Copy
ActiveSheet.Next.Select
ActiveSheet.Paste
then it formats and sorts everything on "Deliverable", and copies it to a new workbook using this:
Sheets("Deliverable").Select
Sheets("Deliverable").Copy
The only issue is when you open up the new workbook that only contains the copy of "Deliverable", it's still linked back to the original macro workbook and you get the security warning. I could care less about this as I know it came from me, but the report is shared outside my organization and I would prefer to avoid questions and/or hassles for my clients.
The new workbook is not macro enabled, and like I said above, contains no formulas, let alone those that reference the original workbook.
What can I do to address this?
OK, the links were being caused by named ranges in the workbook that came over with the copied worksheet. No formulas, just named ranges.
I added this after the worksheet copy and it took care of it.
Dim nm As Name
On Error Resume Next
For Each nm In ActiveWorkbook.Names
nm.Delete
Next
On Error Goto 0
This is a scenario I've encountered pretty regularly - and worked around it rather than try to solve it.
I have a control workbook with the following worksheets
In the workbook is a named range "myData" which is the data in sheet "Data".
The VBA gets data and pastes it in "Data" then renames the range then refreshes the pivot table which uses the named range as its source. Then the routine copies the sheets Array("Pivot", "Data", "notes") into a fresh workbook which gets saved in a different location as "NewWorkbook.xlsx"
Now if I open the NewWorkbook and look at the data source for the pivot it is referring to the original control workbook.
Is there a simple way of making sure the pivot refers to the data in the new workbook? Should I not use a named range?
You need to update the sourcedata of the pivotcache
Sheets(Array("Data", "Pivot", "notes")).Copy
With ActiveWorkbook.Sheets("Pivot").PivotTables(1)
.PivotCache.SourceData = "myData"
.RefreshTable
End With
for instance
You can also click on the Pivot table tab and redirect it's source from there using the "change source" button and then refreshing as well.enter image description here
Hope this helps.
I am new to excel vba and I have some questions regarding referencing a worksheet
I noticed that when I used
Worksheets(3)
The worksheet would be obtained according to the sequence of the worksheet in the workbook
When I used
Worksheets("Name")
It would be retrieved according to the name of the worksheet
However, I found that both approach is troublesome because for method 1, I need to fix the sequence of the worksheet. Once I dragged the worksheet around, the reference would become incorrect.
Method 2 would need me to fix the work sheet name , which is not that flexible.
I noticed that at the left panel of VBA editor, under the Microsoft Excel Objects, whenever the worksheet is created, a new sheet like
Sheet1 (Name) would be created.
Is there any way that I could reference the worksheet based the the Sheet1 variable, which I could fixed it so that I could freely drag the sheet around or change the worksheet name?
Thanks.
The name you refer to is called the CodeName. You can refer to a sheet by this name.
Eg, for your example Sheet1 (Name) can be referenced as
Worksheets("name")
or
Sheet1
Eg Worksheets("name").Activate or Sheet1.Active would both work
Note that you can change this name to something meaningful in the Properties window of the VBA IDE, but you can't change it at run time
I've got an Access 2007 database on which I have created around 15 SQL queries to process specific data, I have created a main frame navigation menu using menus in Access, I now need to extract all th queries to Excel using VBA code, I have managed to do this with the code below by creating a button and specifying this code to it.
Private Sub query1_Click()
DoCmd.TransferSpreadsheet acExport, _
acSpreadsheetTypeExcel9, "Total Users and Sessions", _
"C:\UsersandSessions.xls", , "Total Users & Sessions"
End Sub
Now my problem at the moment is that fine the query is exported to Excel, but it is done so without any formatting applied at all, I would like to add some formatting at least to the headers and maybe a title inside the spreadsheet, and one thing I dont really like is that all records are being started from the first cell. Also I would prefer that if I hit that button again in Access and the Excel spreadsheet has already exists with that query output then when clicked again it will write again to a the next available sheet.
Any suggestions or ideas a very welcome.
The short story, is you can't. You might be able to do some scripting on the Excel side to format the resulting file. If you want something pretty, you probably want to create a report.
You could, instead mount the excel sheet as a table, and then on a separated sheet in the excel file, reference the first sheet, and format the second sheet for viewing.
if you use DoCmd.TransferSpreadsheet and create an original and then edit it so that the formatting is correct, you can then run DoCmd.TransferSpreadsheet again and it will update the file with the values but keep the formatting.
However, if a human then changes the file by adding new tabs, or adding calculations, etc, then the DoCmd.TransferSpreadsheet will no longer work and will fail with an ugly error message. So what we do in our enviroment is DoCmd.TransferSpreadsheet to an original file with formatting, and follow that up in the VBA by copying the file to the users desktop, and then opening that copy so the user doesn't mess up the original source excel file.
This approach is a minimum code, clean, and easy to maintain solution. But it does require a extra "source" or original file to be hanging around. Works in Access 2007.
You also would like the results to end up on a new tab. Unfortunately, I think it will take some excel automation to do that. The VBA inside Acccess can call a function inside the VBA in Excel. That VBA could then copy the tabs as needed.
My idea would be a hybrid of Excel automation from Access and creating a template in Excel as well that would have a data table linked to your query.
To start create your data table in Excel. You can start three rows down and two columns to the right if you want or wherever. Go to your data tab and click access, find your db, choose your query you want to link to, choose table as the radio button but click properties next instead of ok, uncheck the enable background refresh, this part is critical ... under the definition tab in the connection string you will see a part that says Mode=Share Deny Write change that to Mode=Read, this will make sure that the query refreshes without errors from an MS Access VBA while the db is open and will keep your users from writing back to the db in case your query is a writeable query. Once you set that up you can adjust the table formatting however you choose from the table design tab and it will keep that formatting.
For the purposes of this we are going to assume you started the table in cell B4 ,and your named the worksheet CurrentDay, for purpose of the following VBA example be sure to replace that reference with your actual placement.
Next go back to Access and write your VBA first ensure that in your VBA window you have the reference to Microsoft Excel 12.0 Object Library is selected by going to Tools > References and selecting it from the alphabetical listing.
Create your sub as follows:
Sub query1_click()
Dim xl as Excel.Application
Dim wbk as Excel.Workbook
Dim wks as Excel.Worksheet
Dim RC as Integer
Dim CC as Integer
Set xl = New Excel.Application
Set wbk = xl.wbk.Open "X:\Filelocation\FileName.xlsx" 'name and path you saved the file you previously created
xl.Visible = True
'The above is not necessary but you may want to see your process work the first few times and it will be easier than going to task manager to end Excel if something fails.
RC = xl.Application.CountA(xl.wbk.Worksheets("CurrentDay").Range("B:B")) + 3 'This will count the rows of data in your table including your header so you can copy the data to another tab dynamically as the size of your table expands and shrinks we add 3 to it because we started at row 4 and we need the location of the last row of the record set.
CC = xl.Application.CountA(xl.wbk.Worksheets("CurrentDay").Range("4:4")) + 1 'This counts the header row and adds one space because we will use this as a location holder for our copy / paste function
Set wks = xl.wbk.Worksheets.Add
wks.Name = format(date(),"MM_dd_yy") 'this will name the tab with today's date... you can eliminate this step if you just want the sheets to be the generic Sheet1, Sheet2, etc.
With xl.wbk
.Worksheets("CurrentDay").Range(Cells(4,2),Cells(RC,CC)).Copy
.wks.PasteSpecial xlPasteValues 'This pastes the values so that the table links do not paste otherwise every tab would just refresh everyday.
.wks.PasteSpecial xlPasteFormats 'This gets your formatting.
.RefreshAll 'This will refresh your table
Wend
With xl
.Save
.Close False
.Quit
Wend
Set xl = Nothing
Set wbk = Nothing
Set wks = Nothing
End Sub
That should get you to have your data to not start on A1 of your sheets, save your old data each time, and automate the steps from access.