rbi-learning / Today-I-Learned

1 stars 0 forks source link

10/15 Day #3 VBA and Macros #180

Open ajlee12 opened 4 years ago

ajlee12 commented 4 years ago

Morning Exercise Review

TimBits

Using IFS to check multiple conditions

Good reference for IFS: https://exceljet.net/excel-functions/excel-ifs-function

Go through a series of conditions. If a condition is true, the value that follows the condition is returned.

Note that for all these examples, we use A1 cell as the reference.

IFS(MOD(A1, 15)=0,"TimBits", MOD(A1, 3)=0, "Tim", MOD(A1, 5)=0, "Bits")

If no conditions are met, it returns an NA error.

To avoid that, wrap the whole thing in an IFERROR and return a default value in case of errors.

IFERROR(IFS(MOD(A1, 15)=0,"TimBits", MOD(A1, 3)=0, "Tim", MOD(A1, 5)=0, "Bits"), A1)

Another way of supplying default value: Add another set of condition & return value, where that condition evaluates to TRUE all the time.

IFS(MOD(A1, 15)=0,"TimBits", MOD(A1, 3)=0, "Tim", MOD(A1, 5)=0, "Bits", TRUE, A1)

Using nested IF statements

IF(MOD(A1, 15)=0, "TimBits", IF(MOD(A1, 3)=0, "Tim", IF(MOD(A1, 5)=0, "Bits")))

VBA (Visual Basic for Applications)

Can be used to automate tasks across the Microsoft suite.

DEVELOPER Tab --> Visual Basic --> You'll see a Module (Module 1 by default)

Sub (sub procedure)

Reference: https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/sub-statement

Example:

Sub TimBits()
  Range("A1").Value = "HELLO WORLD"
End Sub

Execute the Macro

Declare a variable

For example, we can declare a variable RowNum by writing:

Dim RowNum As Integer

Iterate with a for-loop

Example:

For RowNum = 1 to 100
  '(task to be done for each iteration)
Next

RowNum's value starts from 1, and changes to 2, and to 3...and finally to 100.

Print

Debug.Print ([thing_you_want_to_print])

Turn the code off (i.e. comment it out)

Add ' before the lines of code you want to comment out. The line of code that's commented out will not run.

' Sub TimBits() <== This is a comment>
Sub TimBit() '<== not comment; will run.

Keywords in VBA

These are purple, and they are case-sensitive. e.g. For, Sub, Next, End Sub, As, Range, etc.

Reference: https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/keywords-by-task

Conditional Logic (If, Else)

Example:

If RowNum < 10 Then (execute some task)

ElseIf RowNum < 20 Then (execute some task)

Else (execute some task)

End If

Styling & Formatting with VBA

See image below for reference. Screen Shot 2020-10-15 at 8 31 18 AM

Google is your best friend... Even experienced practitioners can't memorize all the properties and values.

StackOverflow.com is also an awesome place to search for answers, and it's great for all programming languages.

Data Types in VBA

The Set keyword: https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/set-statement

This is a good, short video on how to use Dim and Set.

Exmple: Reference an object in a worksheet

Dim StudentsWorksheet As Worksheet
Dim StudentsTable As Object

Set StudentsWorksheet = Sheets("Students")
Set StudentsTable = StudentsWorksheet.ListObjects("StudentsTable")

*Hint: It's a common convention to group all Dims before Sets.

Confirm that we retrieved the correct object:

Debug.Print(StudentsTable.Range.Rows.Count)

Range covers the entire range including headers.

Dim StudentsBodyRange As Range
Set StudentsBodyRange = StudentsTable.DataBodyRange

*Hint: If you're targeting specific cells/columns/etc., make sure you have the referenced workbook in focus.

Make a random student selector

  1. First, get the number of students by counting the rows.

    Dim StudentsCount As Integer
    StudentsCount = StudentsBodyRange.Rows.Count
  2. Generate a random number between 1 and StudentsCount.

    • Rnd generates a random decimal number between 0 and 1.
    • Multiply Rnd by StudentsCount, and we get a random decimal number between 1 and 64.999*.
    • So we + 1 to allow it to go up to 65.
    • Use Int to round it to an integer.
    • Save this random number to a variable, RandomIndex.
    RandomIndex = Int(Rnd * StudentsCount) + 1
  3. Select a random student row from the table.

    StudentsBodyRange.Rows(RandomIndex).Select