As a side task, I have automated a few reports using Excel and Word. Nothing special, just a pro memoria for next time.
Here is how to set a formula in a cell, using standard matrix notation
Range("D4").FormulaR1C1 = "=R3C2*10"
Range("D4").FormulaR1C1 = "=R[-1]C[-2]*10"
wkbDest.Sheets(destination_sheet).Cells(i, 13).Formula =
"=R[0]C[-1]+R[0]C[-2]+R[0]C[-3]+R[0]C[-4]+R[0]C[-5]+R[0]C[-6]+R[0]C[-7]+R[0]C[-8]+R[0]C[-9]+R[0]C[-10]+R[0]C[-11]"
Copy and paste Charts and Tables into Word
The word document is just a placeholder with links to Excel tables and diagrams. Avoid copy-paste! The operational risk is just gigantic.
Use Alt+F9 to see a text representation of links in Word, so you can know which objects are dynamic. Break those links programmatically in VBA, by iterating over the collection of shapes in Word. After that, re-save document, that is now updated from the Excel.
A picture link works well if the source Excel document IS OPEN. Caution: Updating might go into infinite loop, if the Excel is large.
Find (pesky) formulas in a sheet
Press F5, select Special… , press Formulas and then OK. This selects any cells with formulas.
The curse of large Excel files
When you reach around 10 000 rows of data, generally, all VLOOKUP and formulas and referenced external files, will take considerable time. With organic growth of the business, this is a gradual coming problem.
If Excel sheet updating is heavy, then copy needed data. Using only values, there will be no updating of expressions etc.
wkbDest.Sheets(destination_sheet).Range("A1:T134").Value = _
wkbSource.Sheets(source_sheet).Range("A1:T134").Value
Memo: Do not even try growing with Excel. Go for better software, and admit complexity increasing, even if the tasks are not complicated (i.e reporting).
Memo: Never add to existing files that are large, keep separate data storage files that only updates data. Have a separate file that reads/copies from the data files to a reporting and calculation file. This practice prevents slow and breaking Excel files, that has both calculations and data together (which is a problem as the size grows).
Filling formulas by dragging – in VBA!
Range("C2:C2").Formula = "=B2*$I$2"
Range("C2:C2").Select
Call Selection.AutoFill(Destination:=Range("C2:C" & endrownr), Type:=xlFillDefault)
Finding rightmost cell in a row
Seems the Range object is not reliable enough.
Dim lColumn As Long
lColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column
This will find the last row in a set of data/any column. Range can be used.
endrownr = wkbSource.Sheets(source_sheet).Range("A1").End(xlDown).Row
LastRow = wkbSource.Sheets(source_sheet).Cells(wkbSource.Sheets(source_sheet).Rows.Count, col_loanid).End(xlUp).Row
This will find a specific value in a column:
rownr = wkbSource.Sheets(source_sheet).Columns("A:A").Find(what:=last_date, LookAt:=xlWhole).Row
Working with Arrays
Dim and then redim to set correct size, with
use “Option Base 1” to set the 0-th element of an array.
Dim dest_loans As Variant
ReDim dest_loans(1 To lastrow, 5)
For j = LBound(temp_array, 1) To i - 1
...
Next j
Dates arithmetic to find last months last day
Dim last_month As Date
last_month = Date - Day(Date)
Copy the cell formatting only, to other cells
wkbDest.Sheets(destination_sheet).Range(wkbDest.Sheets(destination_sheet).Cells(1, lColumn), wkbDest.Sheets(destination_sheet).Cells(100, lColumn)).Copy
wkbDest.Sheets(destination_sheet).Range(wkbDest.Sheets(destination_sheet).Cells(1, lColumn + 1), wkbDest.Sheets(destination_sheet).Cells(100, lColumn + 1)).PasteSpecial xlPasteFormats
Appendix : Some general code to handle files
'------------------------------------------------------------------------
' Auxilliary function
' Check open workbook
'------------------------------------------------------------------------
Function IsWorkBookOpen(sWB)
On Error GoTo NotOpen
Workbooks(sWB).Activate
IsWorkBookOpen = True
Exit Function
NotOpen:
IsWorkBookOpen = False
End Function
Dim wkbDest As Workbook
Dim wkbSource As Workbook
Dim destination_sheet As String
Dim source_sheet As String
Dim source_file As String
Dim source_path As String
'--------------------------------------------------------------
' setup data (external file)
'--------------------------------------------------------------
' Path to source data
source_file = "LR Consolidated Deposit Flows.xls"
source_path = "L:\Reports\LR to BM 2 days\"
' Save the active workbook reference
Set wkbDest = ActiveWorkbook
' Check open source file
ret = IsWorkBookOpen(source_file)
If ret = False Then
Set wkbSource = Workbooks.Open(source_path & source_file)
Else
Set wkbSource = Workbooks(source_file)
End If
' Get data from sheets based on last day in month backwards one year
destination_sheet = "LR 2 dep flow"
source_sheet = "Daily Deposits"
wkbDest.Sheets(destination_sheet).Range("A1:T134").Value = _
wkbSource.Sheets(source_sheet).Range("A1:T134").Value