1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft Excel VBA Programming for the Absolute Beginner Second Edition phần 3 pps

50 434 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Procedures And Conditions
Thể loại Tài liệu
Định dạng
Số trang 50
Dung lượng 1,07 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

‘—————————————————————-result = IsNothingOrStraightnumOnes, numTwos, numThrees, _numFours, numFives, numSixes, result result = IsOnePairnumOnes, numTwos, numThrees, _ numFours, numFives,

Trang 1

‘—————————————————————-result = IsNothingOrStraight(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result) result = IsOnePair(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result) result = IsTwoPair(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result) result = IsThreeOfAKind(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result) result = IsFourOfAKind(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result) result = IsFiveOfAKind(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result) result = IsFullHouse(numOnes, numTwos, numThrees, _

numFours, numFives, numSixes, result)

Range(“C12”).Value = result

End Sub

The line continuation (_)character tells VBA that I really want just one line ofcode, but I need to type it on more than one line in the text editor Make surethere is a single space between the last character and the underscore beforeproceeding to the next line

The function procedures GetNumOnes(), GetNumTwos(), GetNumThrees(), GetNumFours(), GetNumFives(),and GetNumSixes()are called from the DisplayResult()sub procedure and they determinethe number of dice with a particular value These functions use numerous If/Then code

T R I C K

Trang 2

structures to check the values of the dice stored in the second row of the spreadsheet (cellsB2 through F2) The random number function Rnd() generated these values earlier in theprogram A variable is then incremented if its associated value is found in a spreadsheet cell.These functions effectively determine how many dice show the value 1, 2, 3, 4, 5, or 6.Private Function GetNumOnes() As Integer

‘Determine the number of dice displayed with a value of 1

Dim numOnes As Integer

If Range(“B2”).Value = 1 Then numOnes = numOnes + 1

If Range(“C2”).Value = 1 Then numOnes = numOnes + 1

If Range(“D2”).Value = 1 Then numOnes = numOnes + 1

If Range(“E2”).Value = 1 Then numOnes = numOnes + 1

If Range(“F2”).Value = 1 Then numOnes = numOnes + 1

GetNumOnes = numOnes

End Function

Private Function GetNumTwos() As Integer

‘Determine the number of dice displayed with a value of 2

Dim numTwos As Integer

If Range(“B2”).Value = 2 Then numTwos = numTwos + 1

If Range(“C2”).Value = 2 Then numTwos = numTwos + 1

If Range(“D2”).Value = 2 Then numTwos = numTwos + 1

If Range(“E2”).Value = 2 Then numTwos = numTwos + 1

If Range(“F2”).Value = 2 Then numTwos = numTwos + 1

GetNumTwos = numTwos

End Function

Private Function GetNumThrees() As Integer

‘Determine the number of dice displayed with a value of 3

Dim numThrees As Integer

If Range(“B2”).Value = 3 Then numThrees = numThrees + 1

If Range(“C2”).Value = 3 Then numThrees = numThrees + 1

If Range(“D2”).Value = 3 Then numThrees = numThrees + 1

If Range(“E2”).Value = 3 Then numThrees = numThrees + 1

If Range(“F2”).Value = 3 Then numThrees = numThrees + 1

GetNumThrees = numThrees

End Function

Trang 3

Private Function GetNumFours() As Integer

‘Determine the number of dice displayed with a value of 4

Dim numFours As Integer

If Range(“B2”).Value = 4 Then numFours = numFours + 1

If Range(“C2”).Value = 4 Then numFours = numFours + 1

If Range(“D2”).Value = 4 Then numFours = numFours + 1

If Range(“E2”).Value = 4 Then numFours = numFours + 1

If Range(“F2”).Value = 4 Then numFours = numFours + 1

GetNumFours = numFours

End Function

Private Function GetNumFives() As Integer

‘Determine the number of dice displayed with a value of 5

Dim numFives As Integer

If Range(“B2”).Value = 5 Then numFives = numFives + 1

If Range(“C2”).Value = 5 Then numFives = numFives + 1

If Range(“D2”).Value = 5 Then numFives = numFives + 1

If Range(“E2”).Value = 5 Then numFives = numFives + 1

If Range(“F2”).Value = 5 Then numFives = numFives + 1

GetNumFives = numFives

End Function

Private Function GetNumSixes() As Integer

‘Determine the number of dice displayed with a value of 6

Dim numSixes As Integer

If Range(“B2”).Value = 6 Then numSixes = numSixes + 1

If Range(“C2”).Value = 6 Then numSixes = numSixes + 1

If Range(“D2”).Value = 6 Then numSixes = numSixes + 1

If Range(“E2”).Value = 6 Then numSixes = numSixes + 1

If Range(“F2”).Value = 6 Then numSixes = numSixes + 1

GetNumSixes = numSixes

End Function

The function procedures IsNothingOrStraight(), IsOnePair(), IsTwoPair(), IsThreeOfAKind(),IsFourOfAKind(), IsFiveOfAKind(), IsSixOfAKind(), IsFullHouse()are called from the Display Result()sub procedure, and effectively score the hand and return a string result

Trang 4

Each of these functions tests for a particular score (for example, one pair, two pair, and soon) indicated by the function name These functions use If/Then/Else structures withnumerous conditional statements I said earlier in the chapter there would be an excessiveuse of conditionals—at this point, it can’t be helped much, but I have used a line continua-tion character (_)in an effort to make the code easier to read

Consider the IsNothingOrStraight() function procedure The six conditionals in the firstIf/Then/Elsestructure are all linked with logical And This means that all conditionals must

be true if the block of code within the first If/Thenstatement is to be executed If the ber of occurrences of each die’s value is equal to or less than one, a nested If/Then/Elsecodestructure is then used to determine if the hand is a “6 High Straight”, a “6 High”, or a “5 High Straight” If one of these conditional statements is true, then the function is assignedthe value of one of the aforementioned strings which is returned to the calling procedure

num-If none of the conditionals are true, the original result is returned Similar logic applies tothe remaining functions and their determination of a score You should study each functioncarefully noting the use of logical operators, parentheses, and If/Then/Elsecode structures

Parentheses can be used to change the order of operator execution in VBAexpressions For example the conditional statement(5 > 4 Or 6 > 3) And 7 < 3evaluates to false whereas the expression 5 > 4 Or 6 > 3 And 7 < 3evaluates

to true

Private Function IsNothingOrStraight(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If (numOnes <= 1) And (numTwos <= 1) And (numThrees <= 1) And _

(numFours <= 1) And (numFives <= 1) And (numSixes <= 1) Then

If (numSixes = 1) And (numOnes = 0) Then

IsNothingOrStraight = “6 High Straight”

ElseIf (numSixes = 1) And (numOnes = 1) Then

Trang 5

Private Function IsOnePair(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If (numOnes = 2) And (numTwos <= 1) And (numThrees <= 1) And _

(numFours <= 1) And (numFives <= 1) And (numSixes <= 1) Then

IsOnePair = “Pair of Ones”

ElseIf (numOnes <= 1) And (numTwos = 2) And (numThrees <= 1) And _

(numFours <= 1) And (numFives <= 1) And (numSixes <= 1) Then

IsOnePair = “Pair of Twos”

ElseIf (numOnes <= 1) And (numTwos <= 1) And (numThrees = 2) And _

(numFours <= 1) And (numFives <= 1) And (numSixes <= 1) Then

IsOnePair = “Pair of Threes”

ElseIf (numOnes <= 1) And (numTwos <= 1) And (numThrees <= 1) And _

(numFours = 2) And (numFives <= 1) And (numSixes <= 1) Then

IsOnePair = “Pair of Fours”

ElseIf (numOnes <= 1) And (numTwos <= 1) And (numThrees <= 1) And _

(numFours <= 1) And (numFives = 2) And (numSixes <= 1) Then

IsOnePair = “Pair of Fives”

ElseIf (numOnes <= 1) And (numTwos <= 1) And (numThrees <= 1) And _

(numFours <= 1) And (numFives <= 1) And (numSixes = 2) Then

IsOnePair = “Pair of Sixes”

Else

IsOnePair = result

End If

End Function

Private Function IsTwoPair(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If (numOnes = 2 And numTwos = 2) Or _

(numOnes = 2 And numThrees = 2) Or _

(numOnes = 2 And numFours = 2) Or _

(numOnes = 2 And numFives = 2) Or _

(numOnes = 2 And numSixes = 2) Or _

(numTwos = 2 And numThrees = 2) Or _

(numTwos = 2 And numFours = 2) Or _

(numTwos = 2 And numFives = 2) Or _

Trang 6

(numTwos = 2 And numSixes = 2) Or _

(numThrees = 2 And numFours = 2) Or _

(numThrees = 2 And numFives = 2) Or _

(numThrees = 2 And numSixes = 2) Or _

(numFours = 2 And numFives = 2) Or _

(numFours = 2 And numSixes = 2) Or _

(numFives = 2 And numSixes = 2) Then

IsTwoPair = “Two Pair”

Else

IsTwoPair = result

End If

End Function

Private Function IsThreeOfAKind(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If (numOnes = 3 And numTwos < 2 And numThrees < 2 And numFours < 2 _

And numFives < 2 And numSixes < 2) Then

IsThreeOfAKind = “Three Ones”

ElseIf (numOnes < 2 And numTwos = 3 And numThrees < 2 And _

numFours < 2 And numFives < 2 And numSixes < 2) Then

IsThreeOfAKind = “Three Twos”

ElseIf (numOnes < 2 And numTwos < 2 And numThrees = 3 And _

numFours < 2 And numFives < 2 And numSixes < 2) Then

IsThreeOfAKind = “Three Threes”

ElseIf (numOnes < 2 And numTwos < 2 And numThrees < 2 And _

numFours = 3 And numFives < 2 And numSixes < 2) Then

IsThreeOfAKind = “Three Fours”

ElseIf (numOnes < 2 And numTwos < 2 And numThrees < 2 And _

numFours < 2 And numFives = 3 And numSixes < 2) Then

IsThreeOfAKind = “Three Fives”

ElseIf (numOnes < 2 And numTwos < 2 And numThrees < 2 And _

numFours < 2 And numFives < 2 And numSixes = 3) Then

IsThreeOfAKind = “Three Sixes”

Else

IsThreeOfAKind = result

End If

Trang 7

End Function

Private Function IsFourOfAKind(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If numOnes = 4 Then

IsFourOfAKind = “Four Ones”

ElseIf numTwos = 4 Then

IsFourOfAKind = “Four Twos”

ElseIf numThrees = 4 Then

IsFourOfAKind = “Four Threes”

ElseIf numFours = 4 Then

IsFourOfAKind = “Four Fours”

ElseIf numFives = 4 Then

IsFourOfAKind = “Four Fives”

ElseIf numSixes = 4 Then

IsFourOfAKind = “Four Sixes”

Else

IsFourOfAKind = result

End If

End Function

Private Function IsFiveOfAKind(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If numOnes = 5 Then

IsFiveOfAKind = “Five Ones”

ElseIf numTwos = 5 Then

IsFiveOfAKind = “Five Twos”

ElseIf numThrees = 5 Then

IsFiveOfAKind = “Five Threes”

ElseIf numFours = 5 Then

IsFiveOfAKind = “Five Fours”

ElseIf numFives = 5 Then

IsFiveOfAKind = “Five Fives”

ElseIf numSixes = 5 Then

IsFiveOfAKind = “Five Sixes”

Else

Trang 8

IsFiveOfAKind = result

End If

End Function

Private Function IsFullHouse(numOnes As Integer, numTwos As Integer, _

numThrees As Integer, numFours As Integer, numFives As Integer, _ numSixes As Integer, result As String) As String

If (numOnes = 3 And numTwos = 2) Or (numOnes = 3 And numThrees = 2) Or _

(numOnes = 3 And numFours = 2) Or (numOnes = 3 And numFives = 2) Or _ (numOnes = 3 And numSixes = 2) Or (numTwos = 3 And numOnes = 2) Or _

(numTwos = 3 And numThrees = 2) Or (numTwos = 3 And numFours = 2) Or _ (numTwos = 3 And numFives = 2) Or (numTwos = 3 And numSixes = 2) Or _ (numThrees = 3 And numOnes = 2) Or (numThrees = 3 And numTwos = 2) Or _ (numThrees = 3 And numFours = 2) Or (numThrees = 3 And numFives = 2) Or _ (numThrees = 3 And numSixes = 2) Or (numFours = 3 And numOnes = 2) Or _ (numFours = 3 And numTwos = 2) Or (numFours = 3 And numThrees = 2) Or _ (numFours = 3 And numFives = 2) Or (numFours = 3 And numSixes = 2) Or _ (numFives = 3 And numOnes = 2) Or (numFives = 3 And numTwos = 2) Or _ (numFives = 3 And numThrees = 2) Or (numFives = 3 And numFours = 2) Or _ (numFives = 3 And numSixes = 2) Or (numSixes = 3 And numOnes = 2) Or _ (numSixes = 3 And numTwos = 2) Or (numSixes = 3 And numThrees = 2) Or _ (numSixes = 3 And numFours = 2) Or (numSixes = 3 And numFives = 2) Then

IsFullHouse = “Full House”

Trang 9

Chapter Summary

In this chapter, you covered a considerable amount of material on some of the tools required

to help you build a strong programming foundation You started by taking an in-depth look

at procedures in VBA; specifically, event, sub, and function procedures You learned how touse and build these procedures while considering the procedure’s scope, available parameters,and return values (function procedures) You even learned how to build new function pro-cedures to use within formulas created in the Excel application Finally, you saw two newcode structures, If/Then/Else and Select/Case and you learned how to use Boolean logicwithin conditional expressions so a program could branch off in different directions interms of code execution In essence, you learned how to write a program that can make simpledecisions

Figure 3.13

The Poker Dice

game board after

two rolls.

Trang 10

CH A L L E N G E S

1 Draw a simple image of a smiley face using MS Paint then load the image into an Image control placed on a worksheet in Excel Using the MouseDown() event pro- cedure of the Image control, write a program that displays a message to the user every time the user clicks on the image The message should tell the user if he

or she clicked on the eyes, nose, mouth, or face of the image and which button they used The message can be displayed with a message box, or in a Label control,

4 Add a few Check Box controls or Option Button controls to a worksheet, then use a Select/Case code structure in a sub procedure that outputs a message to the user telling them which box or option has been selected.

5 Add some features to the Poker Dice program For example, keep a record of a

user’s session ( n games) by outputting the results of each game to a spreadsheet column off the game board Use a static variable to track the row number of the cell you output the results to You can also assign point values to each hand

based on its value and track the user’s point total for a session of Poker Dice To

make getting a good hand more difficult, you can create additional dice images using new colors (blue, green, and so on).

Trang 11

Loops and Arrays 4C H A P T E R

In Chapter 3, “Procedures and Conditions,” you started building your

programming foundation with the branching structures If/Then/Elseand Select/Case In this chapter, you will significantly expand on thatfoundation by learning looping code structures and arrays Loops and arrays arefundamental to all programming languages; they expand the capabilities of aprogram significantly and make them easier to write You’ll begin this chapter bylooking at the different looping structures available in VBA before moving on toarrays

Specifically, this chapter will cover:

Trang 12

Project: Math Game

The Math Game program is a natural choice for programming with a spreadsheet application like Excel The Math Game requires only basic math skills; it may be more fun for kids to play, but it’s a lot of fun for adults to write To play the Math Game, you answer as many questions

as you can in the allotted time After you finish, the questions are reviewed and scored The

Math Game spreadsheet is shown in Figure 4.1

Looping with VBA

Program looping is the repetition of a block of code a specified number of times The number

of times the block of code is repeated may be well defined or based on a conditional statement.All computer languages contain looping structures because these structures are excellent atsolving problems that would otherwise require repetitive code Imagine a program whosefunction it is to search for a specific name in a column of data with one hundred entries Aprogram with one hundred If/Thenstatements testing the value of each cell for the requiredname will solve the problem The program would be technically easy to create, but cumber-some to type the repetitive code and it would look awful Fortunately, we have looping codestructures to help us

Figure 4.1

The Math Game

program

worksheet.

Trang 13

Each execution of the block of code inside a looping structure represents oneiteration of the loop.

Do Loops

Do loops will execute a given block of code repetitively based on the value of a conditionalexpression All Do-Loops require the keywords Do and Loop, plus one additional keyword(Whileor Until)depending on the desired action The keywords are used to build four basicrepresentations of the Do-Loop The first two representations use the keyword Untilwith aconditional statement that determines if, and how many times the code inside the loop exe-cutes With the conditional statement at the end of the loop, the code inside the loop executes

at least one time

Do

‘Block of code executes at least once and continues to loop if condition is false.

Loop Until (condition)

When the conditional statement is at the beginning of the loop, the code inside the loopwill not execute unless the logic of the conditional statement allows it When using Until,the code inside the loop executes if the conditional statement is false

state-‘Block of code executes at least once and continues to loop if condition is true.

Loop While (condition)

When deciding on which representation of the Do-Loop to use, ask yourself whether youneed the code inside the loop to execute at least once If you do, then put the conditional atthe end The choice of Whileor Untildepends on the logic of the conditional expression

Do While (condition)

‘Block of code executes only if condition is true.

Loop

H I N T

Trang 14

Beware of creating loops that never stop repeating, otherwise known as infinite loops When

constructing your Do-Loop, create it with a conditional expression that will change its cal value (true to false and vice versa) at some point during the code’s execution within theloop It is easier to create an infinite loop than you might think The following example issuppose to find the first occurrence of the string Flintstone in the first column of a work-sheet, output a message to the screen, and then quit

logi-Dim I As Integer

I = 1

Do

If (Cells(I, “A”).Value = “Flintstone”) Then

MsgBox (“Yabba Dabba Do! I found a Flintstone in row “ & Str(I))

End If

I = I + 1

Loop Until (Cells(I, “A”).Value = “Flintstone”)

You can use the Cellsproperty to return all or just one cell on a worksheet.Using the Cellsproperty without any parameters returns all cells on the work-sheet

ActiveSheet.Cells

To return a specific cell, you can specify a row and column index For example,the following line of code returns cell D1

ActiveSheet.Cells(1,4)The Cellsproperty is convenient for using inside of loops when the indices forthe row and column are replaced with looping variables Alternatively, you canspecify the column parameter with a string

ActiveSheet.Cells(1,”D”)

The loop will always fail for two reasons First, if the string Flintstonedoes not appear inthe first column of the worksheet, then the loop is infinite because the conditional state-ment at the end of the loop (Cells(I, “A”).Value = “Flintstone”) will never be true Second,even if the string Flintstonedoes appear in the first column of the worksheet, the outputfrom the MsgBox()function will not appear because the conditional statement at the end ofthe loop will be true before the conditional statement associated with the If/Thenstructure

If you find your program stuck in an infinite loop, use Ctrl-Alt-Break to suspendprogram execution

T R I C K

T R I C K

Trang 15

In most cases you can construct a loop with logical expressions that will work with bothWhileor Until, so using one or the other is simply a matter of personal preference The fol-lowing Do-Loopshave the exact same function, but the first loop uses Whileand the seconduses Until.

Dim I As Integer

I = 1

Do

If (Cells(I, “A”).Value = “Flintstone”) Then

MsgBox (“Yabba Dabba Do! I found a Flintstone in row “ & Str(I))

End If

I = I + 1

Loop While (Cells(I, “A”).Value <> “”)

If I change the conditional operator to =, then I change the logic of the conditional ment, so I must use the keyword Untilto get the same result from the loop

state-Dim I As Integer

I = 1

Do

If (Cells(I, “A”).Value = “Flintstone”) Then

MsgBox (“Yabba Dabba Do! I found a Flintstone in row “ & Str(I))

End If

I = I + 1

Loop Until (Cells(I, “A”).Value = “”)

Both of these loops search the first column for the string Flintstone Once the desired string

is found, a message box outputs a statement with the index of the worksheet row in whichthe string was found In both examples, the Do-Loopcontinues until an empty cell is found.Both loops will execute at least once because the conditional expression is at the end of theloop Neither loop will be infinite because Excel will always add empty rows to the end of aspreadsheet as more rows of data are added

Trang 16

The required keywords are For, To, and Next To keep track of the number of iterationsthrough the loop requires a counting variable as well as starting and ending values The key-word Stepis optional but if it’s used, the value that follows it is used to denote the step size

of the counting variable with each iteration through the loop The step’s value can be anypositive or negative integer; the default value is +1 when Stepis omitted Table 4.1 lists a fewexamples of For/Nextloops

The variable Iin Table 4.1 should be declared as an integer prior to use and the ending valuefor the loop is usually another variable rather than a constant In most cases, you will usethe default step size of +1, so the keyword Stepis omitted

Use the statement Exit Door Exit Forto force code execution to leave a loopingstructure and proceed with the first line of code after the loop Normally, Exit Do

or Exit Forwill be within a branching structure (If/Thenor Select/Case) inside ofthe loop

The following example of a VBA function mimics the FACT()function in the Excel tion by calculating the factorial of an integer

applica-T R I C K

For I = 0 To 10 11 iterations: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10

Trang 17

Public Function Factorial(myValue As Integer) As Long

The For/Nextloop is a natural choice, because you need the looping variable to increment

by one with each iteration until it reaches the value of the integer passed into the function.Each iteration through the For/Nextloop multiplies the next factor by the previous result,effectively producing the factorial of the value stored in the variable myValue For example,

if myValueis 5 then the variable factorialValuewill be calculated as 1*2*3*4*5

Finally, consider the most obvious example of looping in spreadsheet applications, which islooping through a range of cells in a worksheet For now, I will illustrate looping through aworksheet range using a For/Nextloop

In the Real World

The factorial function can also be written as a recursive procedure A recursive procedure is one

that calls itself

Public Function Factorial(N As Integer) As Integer

Recursive procedures are most often and most effectively applied to tree-like data structures such as the file system on a computer.

Trang 18

The example above uses one For/Next loop nested inside another For/Next loop to loopthrough the worksheet range D1:G10 The nested (inside) loop will execute 4 iterations witheach iteration of the outer loop In the example just given, the value of J iterates from 4through 7 for each value of I The code loops through the range by rows, as the variable usedfor the row index (I) is also the counting variable for the outer loop The Chr()function isused to convert a numerical input representing an ASCII (American Standard Code for Infor-mation Interchange) value to its corresponding keyboard character; in this case the values

68 through 71 will be converted to the uppercase letters D through G The Chr()function inVBA works with values 0-255 Table 4.2 lists a few of the more common characters in the set.Alternatively, you could replace the Chr()function with the looping variable J; which, inthis case, would make for easier and cleaner code; however, I wanted to introduce the Chr()function since it can be quite useful when working with the Cellsand Rangeproperties

Trang 19

Input Validation

Trusting that a user will input the type of data required by your program is a leap of faith.You can, and should, provide hints to the user indicating the type of data and format yourprogram requires; however, you should also include code in your program to check what theuser enters against a required format The process of checking user input for accuracy is

known as validation Validation should be included whenever input is required from the user

and the format of that input cannot be guaranteed Examples discussed thus far in this bookinclude: the InputBox()function, the Text Box control, and spreadsheet cells This may seemlike a daunting task at first, but asking where the validation code needs to be entered in aprogram and when it needs to run, simplifies the task considerably

Validation with the InputBox() Function

In the Chapter 2 project, the program asked the user to input his or her name and birthday.The program assumed the user would enter the information in the proper format For theuser’s name, the desired format was first name-space-last name and for the user’s birthday,

a date format of month, day, and year (e.g., 3/4/86 or 3-4-1986) The DateValue()function handledsome of the input validation for us by allowing multiple date formats, but more validation

is required

Consideration of where the validation code should go and when it should run is easy withthe InputBox() function The validation should occur as soon as the user enters data Thebest way to determine this is to put the InputBox()function inside a Do-Loop In the Biorhythmsand Time of Your Life project in Chapter 2, user validation could be added as follows:Dim userName As String

Dim userBirthday As Date

Dim nameOk As Boolean

nameOk = True

Do

userName = InputBox(“What is your first and last name?”, “Name”)

If (userName <> “”) Then nameOk = ValidateName(userName)

Loop While (nameOk = False) Or (userName <> “”)

The InputBox()function is inserted inside a Do-Loopwhere the return value is tested by thefunction procedure ValidateName() The ValidateName()procedure returns true if the name sat-isfies the desired format, otherwise it returns false The loop is repeated if the ValidateName()name procedure returns false, or the user hits the cancel button (InputBox() returns anempty string) on the input box

Trang 20

The ValidateName()function procedure accepts the string entered by the user as input andtests for the number of spaces inside the string.

Private Function ValidateName(userName As String) As Boolean

Dim strLength As Integer

Dim I As Integer

Dim numSpaces As Integer

Dim tempString As String

in the string is incremented by one Essentially, the For/Next loop iterates through eachcharacter in the string and counts the number of spaces found within that string If morethan one space is found in the string entered by the user, then the function returns false,otherwise it returns true

For example, if the user enters either of the strings FredFlintstoneor Fred J Flintstonein theinput box, then the ValidateName()function returns false to the calling procedure just after out-putting the message Please enter just two names separated by one spacein a message box

Trang 21

Obviously, the ValidateName() function procedure does not test for all possible mistakesusers might make entering in their names, but it does illustrate how to use input validationwith the InputBox()function To test for other potential errors by the user, simply add morecode (specific to the type of error you are looking for) to the ValidateName()function procedure.

Validation with a Spreadsheet Cell

In older versions of Excel, validation of spreadsheet content meant writing a lot of code toensure the data was of proper type and/or format With the latest versions of Excel, this is

no longer the case Data validation is now included in the Excel application, so you don’tnecessarily have to write any code Figure 4.2 to shows the data validation dialog box (selectData, Validation from the Excel application menu) Use this tool in your spreadsheets toforce validation of data entered by the user If your project creates new worksheets thatrequire data validation, you can use the record macro tool discussed later in this chapter tolearn how to add it to your program

Arrays

Normally, arrays are not discussed until the end of introductory programming books; ever, as you are already familiar with spreadsheet applications, the concept of an array

how-should come easily An array is a variable that can hold multiple values You how-should use

arrays when a related set of values is to be stored in a variable Doing so relieves you fromhaving to declare a new variable with a unique name for each value in the set Arrays areconvenient as they simplify programming code tremendously

A spreadsheet column that contains data is basically the same thing as an array—it’s a group

of related values Each cell within a spreadsheet column containing the related set of values

is referenced by a row and column index Values in an array are also referenced using indices

Figure 4.2

The Data

Validation dialog.

Trang 22

I assume that you organize your spreadsheets in the normal way—by placing data insidecolumns rather than rows—but the argument is the same whether you equate a spreadsheetcolumn or row to an array

Before starting with the simplest example of an array (the one-dimensional array), consider

a sub procedure that uses a worksheet column much as a programmer would use an array

in an application that does not work with a spreadsheet

In previous chapters, and throughout this chapter I use the Cellsproperty ofthe Excel Applicationobject in code examples The Cellsproperty is straight-forward, with a row and column index that corresponds to a single spreadsheetcell Although discussed in detail in Chapter 5, be aware as you look at theexamples in this chapter that the Cellsproperty acts like a function that returns

a Rangeobject consisting of a single spreadsheet cell I have used the Valueproperty of the Rangeobject extensively thus far, but the Rangeobject has manyother properties for the VBA programmer to use besides the Valueproperty,and you will see many examples in this chapter and subsequent chapters

The BubbleSort()procedure sorts a column of integer values from lowest to highest value.Two integer variables and a Boolean variable are all you need

Public Sub BubbleSort()

‘Sorts data in A2:A11 and writes sorted data to B2:B11

Dim tempVar As Integer

Dim anotherIteration As Boolean

Dim I As Integer

Range(“A2:A11”).Copy Range(“B2:B11”) ‘Copy all data to column B

Range(“B1”).Value = “Sorted Data”

Do

anotherIteration = False

For I = 2 To 10

‘Compare and swap adjacent values

If Cells(I, “B”).Value > Cells(I + 1, “B”).Value Then

tempVar = Cells(I, “B”).Value Cells(I, “B”).Value = Cells(I + 1, “B”).Value Cells(I + 1, “B”).Value = tempVar

anotherIteration = True End If

Next I

Loop While anotherIteration

End Sub

H I N T

Trang 23

A For/Nextloop nested inside a Do-Loopwill iterate through a column of 10 values until thedata is sorted from lowest to highest value The nested For/Nextloop effectively pushes thelargest value from wherever it is located to the last position, much like a bubble rising fromthe depths to the surface The For/Nextloop starts at the beginning of the data list and com-pares two successive values If the first value is larger than the second value, then the position

of the two values are swapped with help from the variable tempVar The next two values arethen compared, where the first of these values was the second value in the previous compar-ison (or first if it had been swapped) Please note: the row index in the Cellsproperty uses I + 1,

so the looping variable in the For/Nextloop works from 2 to 11 so that the procedure sorts tenvalues If a swap of two values has to be made, then the Boolean variable anotherIterationisset to true to ensure the outer Do-Loopcontinues with at least one more iteration

Each iteration through the Do-Loopmoves the next largest value in the set down the column

to its correct position Thus, it will take up to n iterations to sort the data, where n is the

number of values in the set This does not make the BubbleSort() procedure terribly cient, but it works well for small data sets The worksheet shown in Figure 4.3 illustrateswhat happens to a set of numbers after each iteration through the Do-Looploop Note thatFigure 4.3 was created for display only; the BubbleSort() procedure sorts values from col-umn A and copies them to column B only

effi-One-Dimensional Arrays

An array is a variable used to hold a group of related values; it must be declared just as avariable is declared An array is declared with a single name and the number of elements(values) that can be stored in the array

Dim myArray(number of elements) As Type

Trang 24

You may also declare arrays using the Publicor Privatekeywords to define the scope as youwould with a regular variable declaration If you do not specify a data type, then, like a variable,the array will be a variant type Arrays may be declared as any available data type in VBA Allelements in arrays with numerical data types are initialized with the value 0 Elements ofstring arrays are initialized with an empty string When specifying the number of elements,you must consider the lower bound of the array The default lower bound is zero.

Dim myArray(10) As Integer

When you need multiple array declarations of the same size, use a constant tospecify the size of the arrays in the declarations

Const ARRAYSIZE=10 Dim myArray1(ARRAYSIZE) As Integer Dim myArray2(ARRAYSIZE) As Integer Dim myArray3(ARRAYSIZE) As Integer Etc.

This way, if you have to edit the size of your arrays, you only need to change thevalue of the constant

Thus, the integer array myArraydeclared above has 11 elements accessed with the indices 0through 10 To override the default, set the lower bound of the array in the declaration.Dim myArray(1 To 10) As Integer

The array myArraynow has just 10 elements because the lower bound has been explicitly set

to one

Use the statement Option Base 1in the general declarations section of a module

to change the default lower bound of all arrays declared in the module to 1

You can initialize a single element in the array as you would a variable, but you mustinclude the index of the element you wish to change

Trang 25

val-Cells(I + 1, “B”).Value = myArray(I)^2

Next I

Now let’s revisit the BubbleSort() procedure, this time using an array The sub procedureBubbleSort2()works exactly like the BubbleSort()procedure, except that the tests and swapsare performed on the values in the set after they have been loaded into an array rather thanjust using the worksheet column

Public Sub BubbleSort2()

Dim tempVar As Integer

Dim anotherIteration As Boolean

Next I

Loop While anotherIteration = True

Range(“B1”).Value = “Sorted Data”

For I = 2 To 11

Cells(I, “B”).Value = myArray(I - 1)

Next I

End Sub

Ngày đăng: 12/08/2014, 16:21

TỪ KHÓA LIÊN QUAN