Using VBA to copy across columns until a date is reached

jaspermowatt

New Member
Joined
Apr 7, 2018
Messages
10
Hello all,

I am trying to create a dynamic cash flow model where I can type in a start and end date, and run the macro, and the the CFM is auto populated i.e. columns are dragged out until the end date is reached.

I have attached an image of a simplified example.

In my head it seems simple, but I am pretty new to the world of macros and I am struggling to make progress. Any help or guidance would be greatly appreciated. Thank you in advance.

J
 

Attachments

  • Screenshot 2020-05-30 at 11.03.23.png
    Screenshot 2020-05-30 at 11.03.23.png
    30.9 KB · Views: 19

Excel Facts

Spell Check in Excel
Press F7 to start spell check in Excel. Be careful, by default, Excel does not check Capitalized Werds (whoops)
BEFORE
Book1
ABCDEFGHIJ
2
3
4Start01/06/2020Period start
5Period end
6End31/05/2025
7CashFrom Ops
8Cash Invest
9Cash from fin
10Total cash0
11
12Expenditure1
13Expenditure2
14Expenditure3
15Expenditure4
16Total spend0
17
18Net cash0
19
Sheet2
Cell Formulas
RangeFormula
E10E10=SUM(E7:E9)
E16E16=SUM(E12:E15)
E18E18=E10-E16


AFTER running CashFlowStructure
Book1
ABCDEFGHIJ
2
3
4Start01/06/2020Period start01/06/202001/06/202101/06/202201/06/202301/06/2024
5Period end31/05/202131/05/202231/05/202331/05/202431/05/2025
6End31/05/2025
7CashFrom Ops
8Cash Invest
9Cash from fin
10Total cash00000
11
12Expenditure1
13Expenditure2
14Expenditure3
15Expenditure4
16Total spend00000
17
18Net cash00000
19
Sheet2
Cell Formulas
RangeFormula
E10:I10E10=SUM(E7:E9)
E16:I16E16=SUM(E12:E15)
E18:I18E18=E10-E16



VBA Code:
Sub CashFlowStructure()
    Dim y As Integer, yrCount As Integer
    Dim startDate As Date, endDate As Date, periodStart As Date, periodEnd As Date
    Dim formulaRng As Range, periodStartCel As Range
    
    Set formulaRng = Range("E7", Range("E" & Rows.Count).End(xlUp))
    Set periodStartCel = Range("E4")
    startDate = Range("B4")
    endDate = Range("B6")
    yrCount = Year(endDate) - Year(startDate)
    
    For y = 1 To yrCount
        periodStart = DateAdd("yyyy", y - 1, startDate)
        periodEnd = DateAdd("yyyy", y, startDate) - 1
    
        With periodStartCel.Offset(, y - 1)
            .Value = periodStart
            .Offset(1).Value = periodEnd
        End With
        formulaRng.Copy formulaRng.Offset(, y - 1)
    Next y
End Sub


You may find this useful
 
Upvote 0
Thank you Yongle, appreciate the time you spent writing that up.
It works for the simple situation I used but I am trying to apply to it another scenario, where I am working in quarters. I hoped I could modify your code to suit, but I am still stumped! I have attached a XL2BB, hopefully it works

Reserves and Resources v1.xlsx
ABCDEFGHIJ
1
2ResourcesTonnesGradeContainedAverage Mining Rate per day
3ktg/tkozDevelopment10
4Indicated82673.1824Production30
5ReservesTonnesGradeContained
6ktg/tkoz
7Probable69423.02674
8Conversion Rate84%97%82%
9Q2Q3--->>Qx
10xProject Start Date01 June 2020Period Start1-Jun-201-Sep-20--->>1-Dec-29
11Construction Duration20 MonthsPeriod End31-Aug-2030-Nov-20--->>27-Feb-30
12Construction End28 February 2022Construction11--->>
13Production Start01 March 2022Production00--->>
14Mine Life8 Years27 February 2030End11--->>
15Days in Period9190--->>
Sheet8
Cell Formulas
RangeFormula
E4,E7E4=C4*K*D4/grm_oz/K
C8:E8C8=C7/C4
G9:H9G9="Q"&ROUNDUP(MONTH(G10)/3,0)
G10G10=C10
H10H10=G11+1
G11:H11G11=EOMONTH(G10,Month_Quarter-1)
G12:H12G12=IF(G11>$C$12,0,1)
G13:H13G13=IF(G11<=$C$13,0,1)
G14:H14G14=IF($D$14>G10,1,0)
G15:H15G15=G11-G10
J10J10=J11-88
J11J11=D14
C12C12=EOMONTH(C10,C11)
C13C13=C12+1
D14D14=C13+(C14*Day_Year)


Thanks once again.
J
 
Upvote 0
Let's address various items ONE at a time to make sure you do not head down in the wrong direction at this early stage
Everything is 100% your choice and nothing is perfect nor totally straightforward, but it always helps to be aware of a few pitfalls BEFORE jumping in.

Consider cashflow by month
Life is not conveniently split into quarters
Are you absolutely certain that you want the cashflow BUILT by quarter ?
You could BUILD the cashflow by month and then auto-summarise by quarter later
Denominate eveything in months (eg Mine life = 96 months NOT 8 years)

In your example, production is 20 months which is 6 quarters and 2 months
I guarantee that using quarters will create a few numerical headaches for you in quarter 7
One OBVIOUS problem is that the values in rows 12 and 13 need to be BOTH 0 and 1 in quarter 7
- if planning to use those values to drive other calculations change those values to days where they add up to the correct number of days each quarter

Use a formula to do ALL calculations re dates
- the eye does not easily spot date errors and they can be very embarassing and costly!
- there is an error in your example
- construction ends a month earlier than you think :unsure: ie on 31 January 2022 (= 20 months from 1 June 2020)
- and consequently mining ends a month earlier on 31 January 2030
The formula required in C12
=EDATE(C10,20)-1
I would make C11 NUMERICAL value 20 and then
=EDATE(C10,C11)-1
 
Upvote 0
Thank you again Yongle, and especially thanks for pointing out my errors.

I am still in the early stages but always good to see these errors early.

I've avoided some issues you mention by being limiting the start dates so certain months. For the time being, I'll keep it to quarters but may explore the monthly option later.

Essentially I am now at the stage where I would like to loop through columns, copy and pasting each column and stopping when I get to the end date.
Reserves and Resources v1.xlsx
ABCDEFGHIJKLMNO
1
2ResourcesTonnesGradeContained
3ktg/tkoz
4Indicated82673.1824
5ReservesTonnesGradeContained
6ktg/tkoz
7Probable69423.02674
8Conversion Rate84%97%82%
9
10xProject Start Date30 June 2020
11Construction Duration24 Months
12Construction End31 May 2022
13Production Start01 June 2022
14Mine Life96 Months31 May 2030
158 Years
16Gold PriceUSD/Oz1250
17Silver PriceUSD/Oz19.8Q3Q4Q1Q2Q3Q4Q1Q2Q3
18Gold Recovery%91%Period Start1-Jul-201-Oct-201-Jan-211-Apr-211-Jul-211-Oct-211-Jan-221-Apr-221-Jul-22
19Silver Recovery%69.90%Period End30-Sep-2031-Dec-2031-Mar-2130-Jun-2130-Sep-2131-Dec-2131-Mar-2230-Jun-2230-Sep-22
20Payable Gold%99.80%PFS pg166Construction111111100
21Payable Silver%99%PFS pg166Production000000011
22Base Rate ShipmentUSD $ (4,194.00)PFS pg166End111111111
23Frequency of ShipmentOnce every:14 daysPFS pg166Days in Period919189909191899091
24Air FreightUSD / kg $ (5.76)PFS pg166Year (Rel. Prod)-2-2-2-1-1-1-111
25InsuranceUSD / 1000 USD $ (0.10)PFS pg166Days in Period b4 Prod-92-92-90-91-92-92-9000
26Treatment ChargeUSD / oz Au $ (0.75)PFS pg166
27State Royalty%-3%
28B2 Royalty%-3%
29
30Mining CostUSD / t moved $ (2.46)PFS pg123+135
31Processing CostUSD / t milled $ (20.46)PFS pg123+135
32TailingsUSD / t ore $ (0.20)PFS pg123+135
33G&AUSD / t ore $ (5.63)PFS pg123+135
34
35
36
37
38
39
40
41
42
43
44
45
46
47xMiningUnitsSourceTOTAL1-Jul-201-Oct-201-Jan-211-Apr-211-Jul-211-Oct-211-Jan-221-Apr-221-Jul-22
48Material MinedktPFS - appendix101097.00375375375143314331433143322082208
49Stripping Ratio:PFS - appendix13.5600014814814814899
50Ore MinedktPFS - appendix6942.0000010101010212212
51Waste MinedktPFS - appendix94153.00375375375142314231423142319961996
52Ore MinedktCalculated6942.550009.59284819.59284819.59284819.5928481212.3076923212.3076923
53Waste MinedktCalculated94154.453753753751422.90721422.90721422.90721422.90721995.6923081995.692308
54Material MinedktCalculated101097.003753753751432.51432.51432.51432.522082208
55
Sheet1
Cell Formulas
RangeFormula
E4,E7E4=C4*K*D4/grm_oz/K
C8:E8C8=C7/C4
C12C12=EOMONTH(C10,C11-1)
C13C13=C12+1
D14D14=EOMONTH(C13,C14-1)
C15C15=C14/12&" Years"
G17:O17G17="Q"&IF(MONTH(G$19)>9,4,IF(MONTH(G$19)>6,3,IF(MONTH(G$19)>3,2,1)))
G18G18=C10+1
H18:O18H18=G19+1
G19:O19G19=EOMONTH(G18,Month_Quarter-1)
G20:O20G20=IF(G19>$C$12,0,1)
G21:O21G21=IF(G19<=$C$13,0,1)
G22:O22G22=IF($D$14>G18,1,0)
G23:O23G23=G19-G18
G24:O24G24=IF(G20=0,ROUNDUP(SUM($G$21:G21)/Quarter_Year,0),ROUNDUP(SUM(G25:$XFD$25)/Day_Year,0))
G25:O25G25=IF(G21=0,G18-H18,0)
G47:O47G47=G18
F48,F50:F51F48=SUM(G48:XFD48)
G48:O48G48=HLOOKUP(G$24,'CFM from PFS'!$S$2:$AD$59,10)
F49F49=F51/F50
G49:O49G49=HLOOKUP(G$24,'CFM from PFS'!$S$2:$AD$59,6)
G50:O50G50=HLOOKUP(G$24,'CFM from PFS'!$S$2:$AD$59,7)
G51:O51G51=HLOOKUP(G$24,'CFM from PFS'!$S$2:$AD$59,5)
F52:F54F52=SUM(G52:AU52)
G52:O52G52=IF(G49>0,G48/(G49+1),0)
G53:O53G53=IF(G49=0,G48,G48-(G48/(G49+1)))
G54:O54G54=G52+G53
Cells with Conditional Formatting
CellConditionCell FormatStop If True
G17:AY114Expression=AND(G$20=0,$C$13>=G$18)textNO
 
Upvote 0
To copy column G across (as many times as required) it is essential that EVERY formula in every cell in column G works when copied to the next column

One cell that does not work is G18

To work when copied across the formula in G18 it should be replaced with
=F19

AND place this formula in cell F19
=C10+1

AND Use custom number format to display the required text in F19

Custom Format.jpg


1. Please confirm that EVERY formula in column G works correctly when pasted manually to column H etc
- if you need nelp making any of the formulas work let me know

2. Do you want the WHOLE column copied across (which is simplest) or something else ?
 
Upvote 0
oops just spotted an error in the above formulas :oops:
- I think you can work it out!
 
Upvote 0
I started with this
- note the formulas in EVERY cell to correctly calculated the dates

Book1
ABCDEFGH
5
6
7
8
9
1030/06/2020
11Construction duration24 months
12Construction end30/06/2022
13Mine Life96 months30/06/2030
14
15
16
17
18Period Start01/07/2020
19Period End30/09/2020
20
Sheet1
Cell Formulas
RangeFormula
C12C12=EDATE(C10,C11)
D13D13=EDATE(C12,C13)
G18G18=F19+1
F19F19=C10
G19G19=EDATE(G18,3)-1


The code below copies the WHOLE of column C for the required number of quarters ending in column AT
The dates run as follows
01/07/2020 - 30/09/2020
01/10/2020 - 31/12/2020
01/01/2021 - 31/03/2021
etc
01/04/2030 - 30/06/2030 (column AT)

VBA Code:
Sub CopyColumG()
    Dim c As Long, cCount As Long
    For c = 2 To WorksheetFunction.RoundUp((Range("C11") + Range("C13")) / 3, 0)
        Range("G:G").Copy Range("F1").Offset(, c)
    Next c
End Sub

Notes

C11
and C13 both contain a number
Custom format used
0 "months"

F19
gets its value from C10. The formula in F19 is
=C10
Custom format used:
"Period End"

The above should do everything you requested :) but let me know if it does not :unsure:
 
Upvote 0
Yongle, that works great, thank you a great deal for your help! Does exactly what I imagined in my head.

All the best,
J
 
Upvote 0
I started with this
- note the formulas in EVERY cell to correctly calculated the dates
The above should do everything you requested :) but let me know if it does not :unsure:

I have just added a button (Developer, button) and assigned the macro to it, and it works perfect. However I cannot change the name of the button. I've tried changing its name in the formula tab as google suggested but that didn't work. If you can advice that would be great?

Many thanks,
J
 
Upvote 0

Forum statistics

Threads
1,215,487
Messages
6,125,086
Members
449,206
Latest member
ralemanygarcia

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top