© Stefano Grazioli - Ask for permission for using/quoting: Source: Excel VBA Programming by John Walkenbach
VBA = VB + Objects (e.g., buttons, cells, charts…) Objects can contain other objects Object model (‘Application’ on top) If plural, then it is a collection of similar objects Application.Workbooks("Book1.xlsx").Worksheets("Sheet1 ").Range("A1") Objects can contain variables (‘properties’) Application.Workbooks("Book1.xlsx").Worksheets("Sheet1 ").Range("A1").Value
Objects can contain procedures (‘methods’) Application.Workbooks("Book1.xlsx") _.Worksheets("Sheet1").Range("A1").Clear() If you omit the top hierarchy, excel uses the active object Range("A1").Value.ToString()
Specific objects are called instances (e.g., “Button1”)’ The code that generates objects is called a class (e.g., the Class Button ). A module is just a file that contains code. Objects (not modules) need to be instantiated with the command New
ActiveWorkbook.Worksheets("Sheet1").Sort _.SortFields.Add Key:=Range("K2:K6"), _ SortOn:=xlSortOnValues, _ Order:=xlDescending, _ DataOption:=xlSortNormal ActiveWorkbook.Worksheets("Sheet1").Sort _.SortFields.Add Range("K2:K6"), _ xlSortOnValues, xlDescending, xlSortNormal
Copy, paste, and adapt Fincal Example
Private Sub FinCalBtn_Click(sender As Object, e As EventArgs) Handles FinCalBtn.Click Dim inputFromUser As String = "" Dim interestRate As Double = 0 Dim principal As Double = 0 Dim numberOfYears As Double = 0 Dim interest As Double = 0 Dim sum As Double = 0 Do Range("A1:B2").Clear() Do inputFromUser = InputBox("Hello! Please enter an interest rate (e.g., 4.750)", "User input window", "0") interestRate = Double.Parse(inputFromUser) Loop While (interestRate 10) interestRate = interestRate / 100 Do inputFromUser = InputBox("Please enter a principal (e.g., no $)", "User input window", "0") principal = Double.Parse(inputFromUser) Loop While (principal <= 0) Do inputFromUser = InputBox("Please enter the time in years (e.g.,7)", "User input window", "0") numberOfYears = Double.Parse(inputFromUser) Loop While (numberOfYears 30) inputFromUser = InputBox("Would you like to see: (a) the interest, (b) the sum of principal + interest, or (c) both a and b (default)", "User input window", "c") interest = principal * ((1 + interestRate) ^ numberOfYears - 1) sum = principal + interest Select Case inputFromUser Case "a" Range("A1").Value = interest.ToString("C2") Range("A1").ColumnWidth = 15 Range("B1").Value = "is the interest that you requested" Case "b" Range("A1").Value = sum.ToString("C2") Range("A1").ColumnWidth = 15 Range("B1").Value = "is the sum of interest and principal" Case Else Range("A1").Value = interest.ToString("C2") Range("A1").ColumnWidth = 15 Range("B1").Value = "is the interest that you requested" Range("A2").Value = sum.ToString("C2") Range("B2").Value = "is the sum of interest and principal" End Select inputFromUser = InputBox("Want to compute more? (y/n)", "User Input Window", "n") Loop While inputFromUser = "y" End Sub
Private Sub FinCal() Dim inputFromUser As String Dim interestRate As Double Dim principal As Double Dim numberOfYears As Double Dim interest As Double Dim sum As Double Do Range("A1:B2").Clear Do inputFromUser = InputBox("Hello! Please enter an interest rate (e.g., 4.750)", _ "User input window", "0") interestRate = inputFromUser Loop While (interestRate 10) interestRate = interestRate / 100 Do inputFromUser = InputBox("Please enter a principal (e.g., no $)", "User input window", "0") principal = inputFromUser Loop While (principal <= 0) Do inputFromUser = InputBox("Please enter the time in years (e.g.,7)", "User input window", "0") numberOfYears = inputFromUser Loop While (numberOfYears 30) inputFromUser = InputBox("Would you like to see: (a) the interest, (b) the sum of principal + interest, or (c) both a and b (default)", _ "User input window", "c") interest = principal * ((1 + interestRate) ^ numberOfYears - 1) sum = principal + interest Select Case inputFromUser Case "a" Range("A1").Value = interest Range("A1").ColumnWidth = 15 Range("B1").Value = "is the interest that you requested" Case "b" Range("A1").Value = sum Range("A1").ColumnWidth = 15 Range("B1").Value = "is the sum of interest and principal" Case Else Range("A1").Value = interest Range("A1").ColumnWidth = 15 Range("B1").Value = "is the interest that you requested" Range("A2").Value = sum Range("B2").Value = "is the sum of interest and principal" End Select inputFromUser = InputBox("Want to compute more? (y/n)", "User Input Window", "n") Loop While inputFromUser = "y" End Sub
Function CalcDelta(sigma As Double, K As Double, S As Double, currDate As Date, expDate As Date, r As Double, optionType As String) As Double Dim d1 As Double Dim t As Double t = (expDate - currDate) / d1 = (Log(S / K) + (r + sigma * sigma / 2) * t) / (sigma * t ^ (1 / 2)) If optionType = "Call" Then CalcDelta = Application.WorksheetFunction.Norm_S_Dist(d1, True) Exit Function End If If optionType = "Put" Then CalcDelta = (Application.WorksheetFunction.Norm_S_Dist(d1, True) - 1) Exit Function End If MsgBox "Option type not recognized" CalcDelta = 0 End Function
Use the recorder to Download a Table from Alpha (you need to be on a lab Machine or on VPN) Examine the code Run the macro
Use the recorder to execute some SQL (you need to be on a lab Machine or on VPN) Run in a command window (start > cmd) runas /netonly /user:”mcintire\your McIntire id” “the path to excel from C:“ runas /netonly /user:”mcintire\sg6m” “C:\Program Files (x86)\Microsoft Office\Office15/Excel.exe“ Examine the code and modify it Note: delete commandtype = 0 Run the macro
Good for simple subs, but significant limitations (next) Use it to find out commands Example: highlight a cell and change the name of a worksheet
Cannot create loops Cannot create If-Then statements Cannot display pop-up messages or custom dialog boxes Cannot create functions Often produces overcomplex code
Sub Life() Dim lifeField As Range Set lifeField = Application.Worksheets("Sheet1").Range("B2:AL40") For i = 1 To 60 Range("A1") = i For Each c In lifeField counter = 0 If c.Offset(-1, -1).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(-1, 0).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(-1, 1).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(0, -1).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(0, 1).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(1, -1).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(1, 0).Interior.Color = vbRed Then counter = counter + 1 End If If c.Offset(1, 1).Interior.Color = vbRed Then counter = counter + 1 End If c.Value = counter Next If i <> 60 then For Each c In lifeField If c > 3 Or c < 2 Then c.Interior.Color = vbWhite End If If c = 3 Then c.Interior.Color = vbRed End If If WorksheetFunction.RandBetween(0, 1000) < 1 Then c.Interior.Color = vbRed End If Next End If Next End Sub