1、第8章 VBA程序设计基础,1,2,【例1-1-1】求解一元二次方程:AX2BXC=0,Dim a, b, c, d As Double a = 1 b = -6 c = 8 d = b * b - 4 * a * c If d = 0 Thenx1 = (-b + Sqr(d) / 2 * ax2 = (-b - Sqr(d) / 2 * aDebug.Print “x1=“; x1Debug.Print “x2=“; x2 ElseDebug.Print “无实数解“ End If,算法描述,算法实现,算法分析:一元二次方程求根公式。,自己动手,1、已知,3,试编程求sgn(x)的值。,算
2、法分析:用分支语句简单列举x的取值情况。,Dim x As Integer Dim z As Doublex = Val(InputBox(“请输入x的值“) If x 0 Thenz = 1 End If If x = 0 Thenz = 0 End If If x 0 Thenz = -1 End If Debug.Print “sgn(x)=“; z,4,自己动手,1、用整数0-6依次表示星期日、星期一、星期六,编程实现下列功能: 用键盘输入一个整数,在显示器上输出对应的中文表示星期几,如果键入的整数范围不在0到6之内,则显示“输入数据错误” 。,5,算法分析:用多重分支语句简单列举x的
3、取值情况。,Dim x As Integerx = Val(InputBox(“请输入x的值(0-6)“) If x = 0 ThenDebug.Print “星期日“ ElseIf x = 1 ThenDebug.Print “星期一“ ElseIf x = 2 ThenDebug.Print “星期二“ ElseIf x = 3 ThenDebug.Print “星期三“ ElseIf x = 4 ThenDebug.Print “星期四“ ElseIf x = 5 ThenDebug.Print “星期五“ ElseIf x = 6 ThenDebug.Print “星期六“ ElseD
4、ebug.Print “输入数据错误“ End If,6,自己动手,1、用整数0-6依次表示星期日、星期一、星期六,编程实现下列功能: 用键盘输入一个整数,在显示器上输出对应的中文表示星期几,如果键入的整数范围不在0到6之内,则显示“输入数据错误” 。,7,算法分析:用多重分支语句简单列举x的取值情况。,Dim x As Integerx = Val(InputBox(“请输入x的值(0-6)“) Select Case x Case 0Debug.Print “星期日“ Case 1Debug.Print “星期一“ Case 2Debug.Print “星期二“ Case 3Debug.P
5、rint “星期三“ Case 4Debug.Print “星期四“ Case 5Debug.Print “星期五“ Case 6Debug.Print “星期六“ Case ElseDebug.Print “输入数据错误“ End Select,8,自己动手,1、乘火车旅行的行李收费标准如下:成年人可免费携带重量20公斤的行李,未成年人可免费携带10公斤的行李,超出这个重量,火车站将加收费用,收费标准是每公斤每百公里收费为0.20元,不足百公里按百公里记。试编程按不同类型的人和行李重量来记收费用。,9,算法分析,10,11,Dim adult, factor As Integer Dim w
6、eight, distance, expense As Doubleadult = Val(InputBox(“是否成年人?(是-输入 1,不是-输入 0)“) If adult = 0 Or adult = 1 Thenweight = Val(InputBox(“请输入行李重量“)distance = Val(InputBox(“请输入乘车里程“)If Int(distance / 100) = distance Thenfactor = Int(distance / 100)Elsefactor = Int(distance / 100) + 1End IfIf adult = 1 Th
7、enIf weight = 20 Thenexpense = 0Elseexpense = (weight - 20) * factor * 0.2End IfElseIf weight = 10 Thenexpense = 0Elseexpense = (weight - 10) * factor * 0.2End IfEnd IfDebug.Print “行李费用=“; expense; “元“ ElseDebug.Print “输入有误“ End If,延伸思考、讨论,1、如何求s=1*2*3*10=10! 2、如何求s=1+3+5+99 3、如何求s=0+2+4+100,12,自己动手
8、,1、编写程序完成求和: S=1+(1+2)+(1+2+3)+(1+2+10)。 如果求S=1! + 2! + 3! + + 10!,试编写程序并比较其同异。,13,算法分析:每个加项都是累加(乘)值。,14,Dim i, s0, s As Long i = 1 s0 = 0 s = 0 Do While i = 10s0 = s0 + is = s + s0i = i + 1 Loop Debug.Print “s=“; s,自己动手,2、有一个分数数列: 求出这个数列前20项之和。 算法分析: 1)后一项的分子=前一项的分子+前一项的分母 2)后一项的分母=前一项的分子,15,16,Dim
9、 upnum, downnum, temp, i As Integernumerator分子,denominator分母 Dim s As Double i = 1 upnum = 2 downnum = 1 s = 0 Do While i = 20s = s + upnum / downnumtemp = upnumupnum = upnum + downnumdownnum = tempi = i + 1 Loop Debug.Print “2/1+3/2+.=“; s,17,【例8-11】试求,。,算法分析: 1)奇数项的符号为+,偶数项的符号为-,即: (-1)n+1,n为所在项的序
10、号 2)每项的分母是对应项的序号,分子为1,即:1/n, n为所在项的序号 3)将上述1)2)每项求和,得到结果,18,Public Sub WhileWend()Dim i As IntegerDim s As Doublei = 1While i = 100s = s + (-1) (i + 1) / ii = i + 1WendDebug.Print “s=“; s End Sub,【例8-12-0】打印如下图形* 算法分析: 1)4行(类似4个学院)-外循环 2)7列(类似7个班级)-内循环,19,20,Dim row, col As Integerrow = 1 col = 1 Do
11、 While row = 4Do While col = 7Debug.Print “*“;col = col + 1LoopDebug.Printcol = 1row = row + 1 Loop,【例8-12】打印九九乘法表。算法分析: 1)9行(类似9个学院)-外循环 2)9列(类似9个班级)-内循环,21,22,Dim i, j As IntegerDebug.Print Space(3);For i = 1 To 9 循环用来生成第一行的数据Debug.Print Format(i, “ 0#“); i输出格式控制NextDebug.Print 用来另起一行输出For i = 1 T
12、o 9Debug.Print i;For j = 1 To 9Debug.Print Format(i * j, “ 0#“);NextDebug.PrintNext,【例8-13】打印如图所示对称三角图形,要求第一行的 * 在第10列。,* * * *,23,算法分析: 1)4行(类似4个学院)-外循环 2)2m-1列(类似2m-1个班级)-内循环,24,Dim i, j As IntegerFor i = 1 To 4 控制输出的行数Debug.Print Tab(11 - i); 定位每行第一个*所在的列数For j = 1 To 2 * i - 1 控制每行输出的*个数Debug.Pr
13、int “*“; 输出*Next jDebug.Print 输出另起一行Next i,延伸思考、讨论,如何打印如下图形?,25,* * * *,*,* *,* *,2、编程求2到100间的所有素数,并求它们的和。算法分析: 1)将(2到100的99个数)看成99个“学院”-外循环 2)再将每个数的因子看成“班级”-内循环,26,27,Dim flag As BooleanDim i, j, s As Integeri = 2s = 0Do While i = 100flag = True 设置标志,假定为素数j = 2Do While j iIf Int(i / j) = i / j Then
14、flag = FalseExit DoEnd Ifj = j + 1LoopIf flag ThenDebug.Print i; Space(2);s = s + iEnd Ifi = i + 1LoopDebug.PrintDebug.Print “2-200间的素数和为:“; s,2、输入两个正整数m和n,求其最大公约数和最小公倍数。 算法分析: (1)变换m、n,使他们变成m=n (2)将m、n同时除以1到m,记录下最大的整除数,就是最大公约数 (3)(m*n/最大公约数)就是最小公倍数,28,29,Dim m, n, t, i, commul, comdiv As Integeri =
15、 1 m = Val(InputBox(“请输入正整数m“) n = Val(InputBox(“请输入正整数n“) If m n Thent = mm = nn = t End If Do While i = mIf Int(m / i) = m / i ThenIf Int(n / i) = n / i Thencomdiv = iEnd IfEnd Ifi = i + 1 Loop Debug.Print m; “和“; n; “的最大公约数是:“; comdiv commul = m * n / comdiv Debug.Print m; “和“; n; “的最小公倍数数是:“; co
16、mmul,3、编程求100到200之间即能被3整除又能被5整除的正整数的个数,并显示这些数。,30,Dim i, num As Integer Debug.Print “100-200间能同时被3和5整除的数是:“ i = 100 Do While i = 200If Int(i / 3) = i / 3 ThenIf Int(i / 5) = i / 5 ThenDebug.Print i; Space(2);End IfEnd Ifi = i + 1 Loop,5、在0至999的范围内,找出所有这样的数,其值等于该数中各位数字的立方和。如:153 = 13+53+33 算法分析: 1)先提
17、取一个3位数的百位、十位、个位数字,如:153拆分为1、5、3。 方法:百位数字n1=int(153/100),十位数字n2=int((153-n1*100)/10),个位数字=153-n1*100-n2*10 2)判断153= n13+n23+n33?,31,32,Dim i, j, n1, n2, n3 As Integer Debug.Print “满足条件的立方数:“ i = 0 Do While i = 999n1 = Int(i / 100)n2 = Int(i - 100 * n1) / 10)n3 = i - 100 * n1 - 10 * n2If i = n1 3 + n2
18、 3 + n3 3 ThenDebug.Print i; Space(2);End Ifi = i + 1 Loop,6、已知二年期人民币整存整取年利率为2.25%,王大妈选择二年期整存整取,存款金额10000元,她希望有1000元以上的净利息。由于银行对最后的利息征20%所得税,故至少要税前为1250元利息,才有1000元的净利息。请你编程帮王大妈算一算,要存几年才能达到她的目标。 算法分析: 利息=本金*利率 净利息=利息 - 利息*20%,33,34,Dim money, rate, interest, netinterest, taxrate, sum, temp As Double
19、Dim i As Long i = 0 money = 10000 rate = 0.0225 taxrate = 0.2 interest = 0 netinterest = 0 sum = 0 temp = money Do While sum 1000i = i + 2 存期interest = temp * rate 利息netinterest = interest - interest * taxrate 税后利息sum = sum + netinterest 总利息temp = money + netinterest 增加利息后的本金 Loop Debug.Print “实现王大妈
20、的目标需要:“; i; “年“,【例8-19】For each遍历数组。,35,Dim strLetters(0 To 6) As String Dim y As Variant 变量y是对象变量,它必须是Variant类型 strLetters(0) = “A“ strLetters(1) = “B“ strLetters(2) = “C“ strLetters(3) = “D“ strLetters(4) = “E“ strLetters(5) = “F“ strLetters(6) = “G“ For Each y In strLettersDebug.Print y; Next,也可以
21、编写成如下语句 Dim strLetters(0 To 6) As String Dim i As Integer strLetters(0) = “A“ strLetters(1) = “B“ strLetters(2) = “C“ strLetters(3) = “D“ strLetters(4) = “E“ strLetters(5) = “F“ strLetters(6) = “G“ For i = 0 To 6Debug.Print strLetters(i); Next,四、数组应用的几个例子,1、使用数组输入十个评委的评分,要求去除最高分、最低分,求应试者的最后得分。,36,算法
22、分析: 1)找到最高分、最低分 2)得分=(十个评委的评分-最高分-最低分),37,Dim score(10), max, min, total As Double Dim i As Integer For i = 0 To 9score(i) = Val(InputBox(“请输入第“ + Str(i + 1) + “位评委的评分:“) Next max = score(0) min = score(0) total = score(0) For i = 1 To 9If score(i) max Thenmax = score(i)End IfIf score(i) min Thenmin
23、 = score(i)End Iftotal = total + score(i) Next Debug.Print “应试者的最后得分是:“; total - max - min,2、(约瑟夫问题)有M个人围成一圈,每人个的编号(1,2,3,M),从第个人数起,报到N时这个人就出圈,再继续数,报到第N个又出圈,出圈人的位置不再数,直到只剩下一个人为止,排出出圈人的顺序。,38,算法分析: 1)定义一个数组w(1 to m)对应每个人的编号,并且每个元素都赋值1; 2)报到数n的人对应的元素值变成0,即出圈; 3)统计值为1的元素的个数,如果值为1,结束报数,值为1对应的元素即为最后出圈者,否
24、则,重复2)。,39,Dim i, m, n As Long m = Val(InputBox(“请输入围圈的人数M。“) ReDim w(1 To m) As Long n = Val(InputBox(“请输入出圈的数字N。“) For i = 1 To m 给所有的人标记值1w(i) = 1 Next i Dim start_pos As Long 记录开始报数的位置 Dim offset As Long 记录从开始报数起报过的人数 Dim n_pos As Long 报到出圈数字N的人的位置 Dim remain As Long 还剩多少人,即值为1的元素的个数 start_pos =
25、 0 从第1个人点起,因为第一个人要算,所以从0起 Do While Trueoffset = 0 重新点过人n_pos = start_pos 确定从那个人点起Do While offset m Thenn_pos = n_pos - mEnd If 点到最后返回第一个If w(n_pos) 0 Then 如果该位置有人,则表示点到人offset = offset + 1 报过数的人数加1End Ifremain = 0 统计剩多少人For i = 1 To mremain = remain + w(i)Next iIf remain 0 ThenDebug.Print iExit For
26、因为只有一个结果,所以这句建议加上,退出循环End If Next i,练习题,一、编一个程序,将华氏温度F=68度变换成摄氏温度C,并将结果显示出来 计算公式为:C=5(F-32)9 二、以循环方式输出1到10的数字 三、求0100之间奇数之和 四、求S=1!+2!+3!+5!的值。 五、S=2+4+6+100 六、Y=1+1/2+1/3+ +1/30,40,七、S=1+(1+2)+(1+2+3)+(1+2+3+4+100) 八、学分在12分以下的收费4000元,若超过12学分,则超过部分每学分加收200元,编一个程序计算收费,输入学分U,求应缴学费T。九、假定对齐的列为20列,编写程序输出下列二种图形,41,# # # # # #,# #,