Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 92 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
92
Dung lượng
20,62 MB
Nội dung
Excel® VBA for Physicists A Primer Excel® VBA for Physicists A Primer Bernard V Liengme St Francis Xavier University, Nova Scotia, Canada Morgan & Claypool Publishers Copyright ª 2016 Morgan & Claypool Publishers All rights reserved No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without the prior permission of the publisher, or as expressly permitted by law or under terms agreed with the appropriate rights organization Multiple copying is permitted in accordance with the terms of licences issued by the Copyright Licensing Agency, the Copyright Clearance Centre and other reproduction rights organisations Rights & Permissions To obtain permission to re-use copyrighted material from Morgan & Claypool Publishers, please contact info@morganclaypool.com Online supplementary data files are available at http://ej.iop.org/images/books/978-1-6817-4461-2/ live/bk978-1-6817-4461-2suppdata.zip ISBN ISBN ISBN 978-1-6817-4461-2 (ebook) 978-1-6817-4460-5 (print) 978-1-6817-4463-6 (mobi) DOI 10.1088/978-1-6817-4461-2 Version: 20161101 IOP Concise Physics ISSN 2053-2571 (online) ISSN 2054-7307 (print) A Morgan & Claypool publication as part of IOP Concise Physics Published by Morgan & Claypool Publishers, 40 Oak Drive, San Rafael, CA, 94903 USA IOP Publishing, Temple Circus, Temple Way, Bristol BS1 6HG, UK To Pauline, my wife, my friend, and my amanuensis, with many, many thanks Contents Preface x Acknowledgements xi Author biography xii Introduction 1-1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 Preparation Demonstrating a simple function Saving a macro-enabled workbook Using constants and VB functions User-defined array function Notes on VBA functions A simple subroutine Linking an image to a subroutine Recording a macro Finding a home for macros Typographical matters Variables, Dim statements, and data types 2-1 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 Naming variables The Dim statement The major reason for variable declarations Declarations in function headers and for constants Data types A second reason for variable declarations Dimensioning arrays The Set statement The With…End With structure 2-1 2-1 2-1 2-3 2-3 2-4 2-4 2-6 2-7 Structured programming 3-1 3.1 3.2 3.3 Branching structures (If and Select Case) Looping structures (For…Next and Do…While/Until) Some further examples 3-1 3-4 3-7 vii 1-1 1-3 1-5 1-6 1-7 1-8 1-9 1-11 1-11 1-14 1-14 Excel® VBA for Physicists The Excel object model 4.1 4.2 4.3 4.6 Examples of properties, methods and events The Range object properties Range object methods 4.3.1 Select, Copy, and Paste 4.3.2 Clear methods 4.3.3 Delete method WorksheetFunction object Workbook and worksheet events 4.5.1 Workbook event 4.5.2 Worksheet event Code for sending email Working with add-ins 5-1 5.1 5.2 5.3 5.4 5.5 5.6 5.7 Creating an add-in Installation Using the add-in Making changes to the add-in Viewing worksheets Protecting the add-in Reversing everything 5-1 5-2 5-2 5-3 5-3 5-4 5-4 Numerical integration 6-1 6.1 6.2 6.3 6.4 6.5 The trapezoid approximation The Simpson 1/3 approximation An aside Monte Carlo integration Gaussian and Romberg integration 6-1 6-4 6-6 6-7 6-8 Numerical methods for differential equations 7-1 7.1 7.2 7.3 7.4 7.5 7.6 Euler’s method The Runge–Kutta fourth-order method Simultaneous OEDs Example of a system of two OEDs Higher order OEDs R–L circuit 7-1 7-4 7-6 7-6 7-8 7-8 4.4 4.5 4-1 viii 4-1 4-3 4-5 4-5 4-7 4-7 4-7 4-12 4-12 4-13 4-14 Excel® VBA for Physicists Finding roots 8-1 8.1 8.2 8.3 8.4 The bisection method The successive iteration method Root finding with Solver Using range names 8-1 8-3 8-4 8-7 ix Excel® VBA for Physicists Figure 7.3 Demonstration of the fourth-order Runge–Kutta method Range(“A13:B13”).Select Range(Selection, Selection.End(xlDown)).Select Selection.ClearContents: Range(“A13”).Select ‘Get data from worksheet X0 = Range(“X0”) Y0 = Range(“Y0”) n = Range(“n”) h = Range(“delta”) ‘Output initial point myrow = 13 Cells(myrow, “A”) = X0: Cells(myrow, “B”) = Y0: myrow = myrow + For j = To n K1 = h * MyFun(X0, Y0) K2 = h * MyFun(X0 + h / 2, Y0 + K1 / 2) K3 = h * MyFun(X0 + h / 2, Y0 + K2 / 2) 7-5 Excel® VBA for Physicists K4 = h * MyFun(X0 + h, Y0 + K3) Y1 = Y0 + (1 / 6) * (K1 + * K2 + * K3 + K4) X1 = X0 + h ‘Output new point Cells(myrow,“A”)=X1:Cells(myrow,“B”)=Y1:myrow=myrow+1 ‘Setup for next iteration X0 = X1: Y0 = Y1 Next j End Sub 7.3 Simultaneous OEDs Consider a pair of simultaneous equations having the form: y′ = g (x , y , z ) u′ = f (x , y , z ) The Runge–Kutta formulas for these equations are: yn−1 = yn + (k1 + 2k2 + 2k3 + k4) u n−1 = u n + (w1 + 2w2 + 2w3 + w4) k1 = hg(xn, yn , u n) w1 = hf (xn, yn , u n) ( w = hf (x k = hg(x w = hf (x 1 1 1 ) w) w) w) k2 = hg xn + h , yn + k1, u n + w1 n + h , yn + k1, u n + n + h , yn + k2, u n + n + h , yn + k2, u n + 1 1 2 2 k4 = hg (xn + h , yn + k3, u n + w3) w4 = hf (xn + h , yn + k3, u n + w3) 7.4 Example of a system of two OEDs Here are a pair of coupled OEDs which we wish to solve over the range ⩽ x ⩽ 2: dy = −0.5y dx dz = − 0.3z − 0.1y dx 7-6 y(0) = z(0) = Excel® VBA for Physicists The VBA for this (see Module3) is: Sub SysOED() Worksheets(“RK3”).Activate ‘Clear any previous results Range(“A11:D11”).Select Range(Selection, Selection.End(xlDown)).Select Selection.ClearContents: Range(“A13”).Select x = Range(“x0”) y = Range(“y0”) z = Range(“z0”) xfinal = Range(“xn”) n = Range(“n”) h = (xfinal − x0) / n t = myrow = 11 Cells(myrow, “A”) = 0: Cells(myrow, “B”) = x Cells(myrow, “C”) = y: Cells(myrow, “D”) = z myrow = myrow + For j = To n k1 = h * g(x, y, z): w1 = h * f(x, y, z) k2 = h * g(x + h / 2, y + k1 / 2, z + w1 / 2): w2 = h * f(t + h / 2, y + k1 / 2, z + w1 / 2) k3 = h * g(x + h / 2, y + k2 / 2, z + w2 / 2): w3 = h * f(t + h / 2, y + k2 / 2, z + w2 / 2) k4 = h * g(x + h, y + k3, z + w3): w4 = h * f(t + h, y + k3, z + w3) t = t + h y = y + (1 / 6) * (k1 + * k2 + * k3 + k4) z = z + (1 / 6) * (w1 + * w2 + * w3 + w4) Cells(myrow, “A”) = j: Cells(myrow, “B”) = t Cells(myrow, “C”) = y: Cells(myrow, “D”) = z myrow = myrow + Next j End Sub Function g(x, y, z) g = −0.5 * y End Function Function f(x, y, z) f = − 0.3 * z − 0.1 * y End Function 7-7 Excel® VBA for Physicists Figure 7.4 shows the RK3 worksheet for n = 20 The reader can experiment with other values; the graph can handle values up to n = 100 The exact solution may be found on the WolframAlpha.com site by entering: solve differential equation y’ = −0.5y, z’ = 3−0.3z−0.1y, y(0) = 4, z(0) = 7.5 Higher order OEDs A second-order OED can be converted to a pair of simultaneous OEDs by simple substitution For example, to solve y″ = ay′ + by + c, we make the substitution y′ = u The introduction of the auxiliary variable u allows us to write the second-order equations as two simultaneous equations: y′ = u u′ = au + by + c 7.6 R–L circuit For our example of solving a second-order ODE we consider the circuit shown in figure 7.5 with R = 15Ω, L = H, and V = 120cos(2t) V We wish to find the instantaneous charge q and the current i for the first five seconds after closing the switch The task is performed on the Circuit worksheet of the Topic7 workbook Our starting assumptions are: dq dq d2q By defintion i= and = dt dt dt dq dq Kirchhoff’s second law L +R = V (t ) dt dt In terms of the Runge–Kutta equations we shall use Figure 7.4 Demonstration of the Runge–Kutta fourth-order method with a system of equations 7-8 Excel® VBA for Physicists Figure 7.5 Sample R–L circuit dq = i = f (t , q , i ) dt di V (t ) − Ri V cos(ωt ) − Ri = = = g (t , q , i ) dt L L It so happens that we need not code the f function since it is simply i = i The following is the code for the subroutine that generated the data in A13:D63 (see figure 7.6, which shows only down to row 34): Dim R, L, V, omega Sub Circuit() Worksheets(“Circuit”).Activate ‘Clear any previous results Range(“A13:B13”).Select Range(Selection, Selection.End(xlDown)).Select Selection.ClearContents: Range(“A13”).Select R = Range(“resist”) L = Range(“Induct”) i = Range(“I0”) q = Range(“Q0”) V = Range(“V0”) omega = Range(“omega”) h = Range(“h”) t = tfinal = myrow = 13 Cells(myrow, “A”) = 0: Cells(myrow, “B”) = t Cells(myrow, “C”) = q: Cells(myrow, “D”) = i myrow = myrow + n = tfinal / h For j = To n k1 = h * i: w1 = h * g(t, i) k2 = h * (i + w1 / 2): w2 = h * g(t + h / 2, i + w1 / 2) 7-9 Excel® VBA for Physicists Figure 7.6 Output from the Circuit subroutine k3 = h * (i + w2 / 2): w3 = h * g(t + h / 2, i + w2 / 2) k4 = h * (i + w3): w4 = h * g(t + h, i + w3) t = t + h q = q + (1 / 6) * (k1 + * k2 + * k3 + k4) i = i + (1 / 6) * (w1 + * w2 + * w3 + w4) Cells(myrow, “A”) = j: Cells(myrow, “B”) = t Cells(myrow, “C”) = q: Cells(myrow, “D”) = i myrow = myrow + Next j End Sub Function g(t, i) g = (V * Cos(omega * t) − R * i) / L End Function One item in the code needs an explanation The values for R, L, V, and omega are obtained from the worksheet in the subroutine but are not passed to the function g By dimensioning these variables external to the subroutine, they are made globally available within the current module 7-10 Excel® VBA for Physicists Also shown in figure 7.6 is a plot of both V(t) and i(t) to demonstrate the concept of phase shift The worksheet (but not the figure) has a plot comparing the approximate i(t) values to the exact i(t) values The exact solution for i(t) is i (t ) = ⎛ ⎛ R ⎞⎞ V0 ⎜R cos(ωt ) + ωL sin(ωt ) − R exp ⎜ t⎟⎟ 2⎝ ⎝ L ⎠⎠ R +ωL See http://info.ee.surrey.ac.uk/Teaching/Courses/ee1.cct/circuit-theory/section6/ sinresponse.html 7-11 IOP Concise Physics Excel® VBA for Physicists A Primer Bernard V Liengme Chapter Finding roots There are several numerical methods for finding roots, including the Newton– Raphson, Secant, and bisection methods There is also the method called ‘successive iterations’, which is not often included in textbooks but which, in appropriates cases, can be the quickest one to implement In this section we see how to implement the bisection and the successive approximations methods We shall also see how to implement the Excel Solver function in VBA code to find the roots of functions 8.1 The bisection method In figure 8.1 the upper graph shows a plot of x + 0.9x − 2.3x + 3.6x − 25.2 from −4 ⩽ x ⩽ 3.5 Clearly there is a root between −4 ⩽ x ⩽ 3.5 and another between ⩽ x ⩽ In general, let f(a) and f(b) have different signs (so f(a) × f(a) < 0); if we locate the midpoint x = (a + b)/2 then one of three cases applies: ⎧< there is a root in[a , x ] ⎪ f (a )f (x )⎨< there is a root in[x , b ] ⎪ ⎩= then x is the root If one of the first two cases is true, we let b = x or a = x, respectively, and repeat the process of locating the midpoint x = (a + b)/2 until f(x) is zero or approximately so The bisection method will never fail provided we start with a and b values such that f(a) × f(b) < These can be found programmatically, but a graphical method is easier to implement In the worksheet Bisect of Topic8.xlsm (figure 8.1): (i) B3 and B4 have the names show in A3:A4; (ii) the formula in A8 is =xstart; (iii) in A9 we use =A8+h and this is copied down to A107; and (iv) in B8 the formula =f(A8) evaluates the required function for the first x value, this is copied down to B107 So we have 100 points to plot The lower chart shows the author’s starting point of xstart = −10 with h = 0.5 Subsequent experiments quickly generated the top chart, giving us a pair of a and b values to use with the Bisection function doi:10.1088/978-1-6817-4461-2ch8 8-1 ª Morgan & Claypool Publishers 2016 Excel® VBA for Physicists Figure 8.1 The bisection method From the graph we read off −4 and −2 and enter these values into J8:K8, cell L8 calls the Bisection function with =Bisection(J8,K8) to find an x that gives f(x) = M8 uses =f(L8) to test this x value Similarly, in J9:M9 we find the root that lies between 1.5 and 2.5 Below that we show how slightly different starting a and b values can subtly effect the root that is found by bisection The code for the two functions (Module1) is: Function f(x) f = x ^ + 0.9 * x ^ − 2.3 * x ^ + 3.6 * x − 25.2 End Function Function Bisection(a, b) n = If f(a) * f(b) > Then ‘Inappropriate starting values Bisection = “N/A” Exit Function End If Do x = (a + b)/2 Select Case f(a) * f(x) Case Exit Do Case Is < b = x 8-2 Excel® VBA for Physicists Case Is > a = x End Select n = n + If n > 10000 Then Exit Function Loop While Abs(f(x)) > 0.00000000001 Bisection = x ‘Debug.Print “n= “ & n End Function The purpose of the n variable is to cause the function Bisection to end after 10,000 iterations The author hates having the problem of a never ending loop (this would happen, for example, if Loop While Abs(f(x)) > 0.00000000001 had been mistyped as Loop While Abs(g(x)) > 0.00000000001) because there have been times when ESC or CTRL+BREAK failed to arrest an errant loop If the reader wishes to see how many iterations are required, just remove the apostrophe from the start of the Debug.Print statement and recalculate all of the L8:L11 cells The Immediate window shows that generally less than 100 iterations are needed 8.2 The successive iteration method If we can write our problem in the form x = g (x ) and we have some information about x, then we may use an initial approximation (a guess), substitute it into g (x ), and find a better approximation Figure 8.2 show an example; since the left-hand side of the original equation has a small value, we may assume that x is small so we make the initial value zero The first approximation is 0.01296, this leads to the third approximation of 0.1253, and so on Eventually we have successive approximations that are the same or differ by very little Figure 8.2 The successive iteration method 8-3 Excel® VBA for Physicists For a more interesting example we set ourselves the task of finding the molar volume of CO2 at atm and 500 K using the van der Waals equation; given for CO2, a = 3.592 L2 · atm·mole−1 and b = 0.04267 L·atm a The van der Waals equation (p + )(V − b ) = RT may be rewritten as V a V = RT (p + )−1 + b so we have the expression x = g(x) needed for the method V For our initial V value, we turn to the ideal gas law Figure 8.3 shows the worksheet SuccIter; the code for the function is: Function SuccIter(p, T, a, b, R) Flag = True V = R * T * p Do Until Flag = False Vold = V V = R * T/(p + a/Vold ^ 2) + b If Abs(Vold - V) < 0.0000001 Then Flag = False n = n + If n > 100 Then Exit Do Loop SuccIter = V End Function 8.3 Root finding with Solver The built-in Solver feature of Excel can be used to find roots Here we will see how to incorporate calls to Solver within a VBA subroutine It will be assumed that the reader’s Excel has Solver available (check in the Data tab to see that the last group is named Analyze and contains a Solver command); if not, this website will guide you through the process: https://msdn.microsoft.com/en-us/library/office/ff196600.aspx We have been asked to find all the real roots of cos(2x ) − 0.4x = on [−4, +6.5] Figure 8.4 shows part of the worksheet Solver in Topic8.xlsm Using a value of −4 for xstart and 0.105 for h, we find that the function crosses the x-axis three times between −4 and and is moving away from the axis as x increases This gives us three pairs of starting values for a and b as shown in D22:E24 We select D21:G24 Figure 8.3 van der Waals calculation 8-4 Excel® VBA for Physicists Figure 8.4 Solver called from a VBA function and use Formula | Defined Names | Create from Selection to name four sets of three cells Note that G22:24 has the name g_x not g(x) We need some good starting values for the three x values so we code a subroutine (ResetProb) to give them each the values (a + b )/2 The code for this and for the subroutine (SolverSub) are found in Module2 and are: Function g(x) g = Cos(2 * x) − 0.4 * x End Function Sub ResetProb() For n = To Range(“x”).Count Range(“x”)(n) = (Range(“a”)(n) + Range(“b”)(n))/2 Next n End Sub Sub SolverSub() SolverReset SolverOk MaxMinVal:=0, ValueOf:=0, ByChange:=“x”, Engine:=1,_ EngineDesc:=“GRG Nonlinear” 8-5 Excel® VBA for Physicists SolverOptions MaxTime:=0, Iterations:=0, Precision: =0.000000000001, Convergence:= _ 0.000000000001, StepThru:=False, Scaling:=True, AssumeNonNeg:=False, Derivatives:=1 SolverAdd CellRef:=“g_x”, Relation:=2, FormulaText:=“0” SolverAdd CellRef:=“x”, Relation:=3, FormulaText:=“a” SolverAdd CellRef:=“x”, Relation:=1, FormulaText:=“b” SolverSolve Userfinish:=True End Sub The RestProb code has the statement Range(“x”)(n) = …; this uses a range method which was only briefly mentioned in chapter The (n) part tells VBA to use the nth cell in the range named x The code for SolverSub looks formidable but most of it was generated by manually setting up the Solver model while running the VBA recorder The resulting code had a few unnecessary duplicate statements but with experimentation one is able to obtain a working subroutine It will be helpful to see the Solver model (figure 8.5) generated by the code so we can give some explanations In the SolverOptions statement the phrase Precision:=0.000000000001 refers to the constraint precision; one of our constraints is setting the g_x-values to zero, and we wish to get as close to zero as possible In the SolverAdd statements we have Relation: = 2, etc A visit to https:// msdn.microsoft.com/en-us/library/office/ff196600.aspx and opening the SolverAdd Function link gives us the meanings of these values as shown in table 8.1 below The final statement SolverSolve causes Solver to execute and solve the model Without the parameter Userfinish:=True would result in the final Solver dialog Figure 8.5 The Solver model generated by the VBA code 8-6 Excel® VBA for Physicists Table 8.1 The Relation parameter for SolverAdd Relation Meaning ⩽ = ⩾ CellRef must have final values of integers CellRef must have finals value of or CellRef must have final values that are all different and integers Figure 8.6 Referencing Solver being displayed ready for the user to click the OK button But the parameter results in this being automatic There is one important step to make after writing or recoding the SolverSub procedure In the VBE window with Module2 open, click the Tools icon and select References to obtain the dialog shown in figure 8.6 Ensure that the Solver box is checked This step needs be done just once—when initially working on the code 8.4 Using range names Some notes on using range names rather than cell references in VBA procedures: i Suppose we have a subroutine with a statement such as Pi = Range (“B12”).Value But someone later decides the worksheets need some tidying up and moves a few things around resulting in the formula =Pi() now being in D10 not B12 The VBA sub will be unaware of this move and will work with whatever is in B12 Had B12 been named as ‘PiValue’ and 8-7 Excel® VBA for Physicists the sub used Pi = Range(PiValue”).Value, then no matter what is added/deleted in the worksheet (other than deleting that cell!), all will be well since the location of the named cell must be resolved at run time ii It is easier to understand both the Solver model dialog and the statements in the sub iii If we wished to modify the worksheet to solve another problem with a different number of roots, all we need is select D21:G21 and the appropriate number of rows, and use Formula | Defined Names | Create from Selection to redefine a, b, x, and g_x In the graph, the three red squares are a plot of F22:G24 and after running SolverSub these markers will be on the x-axis The data in I22:J24 show the results from the Bisection2 function (also in Module2); the code for this is the same as in the first bisection example but it calls upon the g(x) not the f(x) function The values in K22:K24 show that the roots found by the Solver and the bisection methods differ by insignificant amounts 8-8 .. .Excel? ? VBA for Physicists A Primer Excel? ? VBA for Physicists A Primer Bernard V Liengme St Francis Xavier University, Nova Scotia, Canada Morgan & Claypool Publishers Copyright ª 2016 Morgan... statement The major reason for variable declarations Declarations in function headers and for constants Data types A second reason for variable declarations Dimensioning arrays The Set statement The... Physics Excel? ? VBA for Physicists A Primer Bernard V Liengme Chapter Variables, Dim statements, and data types 2.1 Naming variables The rules for naming variables are simple: i You can use letters and