Excel : Printing all workbook but with refreshing (recalculating) each tab before printing it - vba

I am having some issues with printing an excel file i'm using.
The file is made of a mastersheet, and several sheets that contain individual reports (using data in the mastersheet).
The sheets are generated from a template by a macro, and are automatically named. The sheet name is referenced in the sheet, and I am using Index/match to pull the data I need from the mastersheet. So this means that the tabs need to be recalculated constantly when I switch between them (and there's a little piece of VBA code that does it perfectly).
My issue is that when I want to print the individual reporting sheets, they are all printed with the same data (because their contents are not refreshed individually before printing).
Is there any way of printing them without selecting them one by one and individually printing them each time ?
I thought about some macro/vba code that would copy paste the sheets as values in another workbook, and then printing this workbook, but I'm not sure if its the optimal or quickest way of doing things. I would appreciate it if someone could help me.
Thanks !

Here's a start for you
Sub S
Dim ws as worksheet
For each ws in worksheets
ws.calculate
'or call your recalc routine
ws.printout
next ws
end sub

Related

Removing links from copied worksheet

What I want to do
I want a code in my workbook (wbDestination) that opens another workbook (wbBosOriginal) and copies an entire sheet as values (wbBosOriginal has a lot of code in it, in modules and in the worksheet in question, and I do not want this code because it references stuff in wbB that doesn't exist in wbDestination). I have had great problems pasting as values, because it will not paste columns and rows that are currently hidden. So this is why I decided to import the whole sheet instead.
What I tried and what's wrong with it
Here is a block of code I used to copy the worksheet in the destination workbook, in the last index position. The problem with it is that some links still exist to the old workbook (Formulas, validation lists, conditionnal formatting). I have deleted all these links but STILL when I paste the sheet successfully, save and reopen, I have an error saying some content is unreadable. I believe there are still some elements linked to the old workbook.
Set wbBosOriginal = Workbooks.Open(strChosenPath, ReadOnly:=True)
With wbBosOriginal.Sheets("BOS")
.Visible = True
'Pastes the ws in last position in wbDestination
.Copy after:=wbDestination.Sheets(wbDestination.Worksheets.Count)
Set wsNewBos = Worksheets(Worksheets.Count)
'Deletes VBA code in the copied sheet
ThisWorkbook.VBProject.VBComponents.Item(wsNewBos.CodeName).CodeModule.DeleteLines 1, _
ThisWorkbook.VBProject.VBComponents.Item(wsNewBos.CodeName).CodeModule.CountOfLines
End With
The worksheet is successfully pasted with no code in it, with everything else it had previously. I then remove all formulas, conditionnal formatting, and validation lists. Even after removing those as well, I still get an error when opening the workbook.
My question
Apart from conditional formatting, validation lists, VBA code, and formulas linking a worksheet that was pasted to a new workbook, what other elements could cause the workbook from opening in repair mode every time due to existing links to the old workbook?
If my question is not clear, comment and I will clarify.
Dealing directly with VBE seems a bit heavy-handed to me. If your code is manipulating several workbooks, I would put the code in an add-in and not have it in any workbook. (Technically *.xlam addins are workbooks, but when I say "workbook" I mean normal *.xls, *.xlsx, *.xlsm, etc.)
That said, if you're just copying cell values (which may be formulas) between different workbooks, you shouldn't have any dependencies other than cell references, named ranges, and user-defined functions in the original workbook. I would make sure there are none of those. Please also share how you are ensuring your formulas do not have broken references.
If the issue you are having is caused by trying to avoid hidden columns and rows not allowing pastevalues, why not unhide the rows and columns and then copy only the values to the new book?
Just cycle through each of the sheets in the original book and use the method .UsedRange.Hidden = False. As far as I am aware, this should unhide every cell on the sheet and allow you to do the original pastevalues calls
This works fast and smooth (it's harder to delete ALL the data Imo):
Sub tests()
Dim AllRange As Range: Set AllRange = ActiveSheet.UsedRange
Dim ItemRange As Range
Dim myWbDestination As Workbook: Set myWbDestination = ThisWorkbook
Dim SheetDestination As String: SheetDestination = ("Sheet2")
For Each ItemRange In AllRange
With myWbDestination.Sheets(SheetDestination)
.Range(ItemRange.Address) = ItemRange.Value
End With
Next ItemRange
End Sub
Repair mode can be triggered by many factors, you would need to post the code you are getting to look for an explanation, it would be like asking why vba may broke

Reference an excel sheet from another workbook without copying the sheet

Im wondering if it's possible to reference an excel sheet from another work book without making a copy of that sheet?
The situation : I have some very large worksheets filled with various data, but i don't want to keep a copy of them open in my workbooks because while each workbook uses the same data source, they're slightly different.
I have a vba routine that takes this data and creates input files for other codes, vba expects this data to be available on the defined sheet names.
Is it possible to make either excel or vba to know that when i request worksheet("Example_1") it instead knows that i mean example_1 from a different workbook?
Thanks
Yes, it is possible.
You need to add those lines to your code:
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Set wkb = Excel.Workbooks("name_of_workbook.xlsx")
Set wks = wkb.Worksheets("Example_1")
Now, every time you want to refer to a range from this other workbook, you need to add wks. before, i.e.:
'Printing value in cell.
wks.Range("A1") = "x"
'Selecting range.
call wks.Range(wks.Cells(1,1), wks.Cells(2,2)).Select
=SUM('C:\test\[test.xlsx]sheet_name'!A1:A25)
is an example of a formula which references sheet sheet_name in workbook C:\test\text.xlsx.
Note that when the other workbook is opened, the formula automatically changes to
=SUM([test.xlsx]sheet_name!A1:A25)
and then when it is closed, the formula will change back.

Excel VBA - Formatting script for automation

So here's what I'm trying to do:
Open file: Pc_Profile
Create new sheet: Sheet1
Copy desired cells from Pc_Profile to Sheet1 (see script below)
Copy entire Sheet1 to new excel file: db.xls
Rename sheet to content of cell A5
Create new sheet for next script run
Basically I'm trying to automate an extraction of a TON of excel files into a single organized file. Each script call should extract to its own sheet so there's no overwritten information.
Here is what I have working so far. It just copies the desired cells to a new sheet within the same file.
' Create Excel object
Set objExcel = CreateObject("Excel.Application")
' Open the workbook
Set objWorkbook = objExcel.Workbooks.Open _
("\\[directory]\Pc_Profile.xls")
' Set to True or False, whatever you like
objExcel.Visible = True
objWorkbook.Worksheets("Pc_Profile").Range("A5:D5").Copy
objWorkbook.Worksheets("Sheet1").Range("A1").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A8:B8").Copy
objWorkbook.Worksheets("Sheet1").Range("A2").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A13:B13").Copy
objWorkbook.Worksheets("Sheet1").Range("A3").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A15:D17").Copy
objWorkbook.Worksheets("Sheet1").Range("A4").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A24:E26").Copy
objWorkbook.Worksheets("Sheet1").Range("A7").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A28:B30").Copy
objWorkbook.Worksheets("Sheet1").Range("A10").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A43:B43").Copy
objWorkbook.Worksheets("Sheet1").Range("A13").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A45:B45").Copy
objWorkbook.Worksheets("Sheet1").Range("A14").PasteSpecial
' Activate Sheet2 so you can see it actually pasted the data
objWorkbook.Worksheets("Sheet2").Activate
I would really appreciate the extra push. I'm automating this for a work project and have no experience with VB - I just learned that on the go.
A couple things that are good practice to get into before I get to your actual question:
1) Any macro that you expect to run a long time should have Application.ScreenUpdating = False before any actual work is done in the code, this tells Excel not to bother with changing what's displayed on the screen (big performance booster). Be sure to include an Application.ScreenUpdating = True near the end of your code
2) Similar to #1, you generally want to include Application.Calculation = xlManual to boost performance. If you have large ranges of cells that your macro needs accurate up-to-date values from, it may be easier to leave the calculation automatic, but that doesn't appear to be the case in this instance.
3) You don't need to create a new Excel instance (which is what your first line of code does). You're already in a perfectly good instance of Excel. This also saves you having to close the other instance at the end of the macro (or worse from forgetting to do so and having memory get hogged by Excel processes that aren't really in use)
As to your specific problem, it sounds like you have more workbooks that Pc_profile to copy from, and that you're wanting to create a new "db.xls" with each run of the macro. Based on those assumptions all you need to do is nest your code starting with 'Open the workbook and objWorkbook.Worksheets("Sheet1").Range("A14").PasteSpecial inside a Do While loop. The thing I'm not sure about is how to control the loop. If the list of files is always the same, you should just include a list on a sheet in the workbook that holds the macro and just iterate through that.
The other thing you should do for ease of coding, and to make the loop more effective is declare and use a Worksheet variable and set if for each workbook to the appropriate sheet to pull data from. Ex.
Dim ws as Worksheet
'The Dim is outside your loop, but this would be inside it
Set ws = objWorkbook.Worksheets("whatever_the_sheet's_name_is")
This way you can replace each occurrence of objWorkbook.Worksheets("Pc_Profile"). with ws., easier to type, easier to read, easier to update, and less error prone.
Next, you don't actually have code for moving Sheet1 to a new workbook, or renaming it. To move it (as well as the other Sheet1's yet to be created), you should, before getting to the Do While loop, have the following
Dim target as Workbook
Set target = Application.Workbooks.Add
Then at almost the end of the loop, you need objWorkbook.Worksheets("Sheet1").Move Before:=Target.Sheets(1)
Last, you need to include objWorkbook.Close SaveChanges:=False after you've moved Sheet1 out of the Pc_Profile and renamed it.

Break connections in excel while keeping values in cells

I have an excel workbook which has 5 worksheets. The back 4 worksheets are filled from queries in Access with values for a summary. The front worksheet is formated all nicely and has graphs and such. The values in the tables on the front sheet are pulled from the back sheets by setting the cell formulas to something like this:
= BackSheet1!A1
This works great but now I need to keep the values in the cell and break the connection so I can delete the back 4 worksheets (because thats what the boss wants).
So my question is about the execution of this. My initial idea is to create a button and put some vba behind it that pulls the values and puts them into a sixth sheet, then deletes the old 5 sheets. Is there a better way? Can I call an excel chunk of VBA from Access VBA so this happens upon creation of the file? Any other thoughts or tips are appreciated.
Thanks.
I went ahead and used the record macro feature in excel, the copy and paste values behind a button in the macro, then coded in deletion of my other pages.
'delete other sheets
Application.DisplayAlerts = False
For Each ws In Sheets
If ws.Name <> "Summary" Then ws.Delete
Next
Application.DisplayAlerts = True
So I got out of this rut in about 20 minutes with only typing 5 lines of code.

Vb.net Updating excel formula with references to other workbooks

I am trying to update some formulas from one workbook, to another workbook. Everything is working great until I run into a formula that has a reference to another workbook. For example a formula like this =IF(ISERROR(W!Var1),0,W!Var2) It will prompt me to open this workbook, I am assuming so that it can evaluate the formula. So my question is this. Is there a way for me to handle these situations on the fly, so if there is a workbook reference needed it will prompt me and then save it to memory? Because if I have more than one cell that contains these formulas it will prompt me to open the referenced workbook for every cell that contains the link. Alternatively, is there a way that I can just push my formula into the cell without having excel evaluate it?
So in my code I have this line which works for any value that doesn't contain a workbook reference. TheRange.RefersToRange.FormulaR1C1 = RangeFormula
Any help is greatly appreciated.
I understand that you refer to Worksheets (each of the "tabs" in a given Excel file), the Workbook is the whole file. The popping-up message appears when the referred Worksheet cannot be found. Example: range.Value = "=sheet5!A3" (in a Workbook having just "sheet1", "sheet2" and "sheet3"). If you want to avoid this message (although bear in mind that the Worksheet is not there and thus the calculations will be wrong anyway), you can write:
excelApp.DisplayAlerts = False
Where excelApp is the Excel.Application you are currently using.