Code archives/Graphics/X-Y 2D Graphs
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This program consists of several interesting routines: (1) A grid graph generator that can be scrolled up-down and left-right, and can be zoomed using the A and Z keys. (2) Code for generating two straight lines at random, then: (a) the two line equations are determined, and (b) Cramer's Rule is used to determine if the lines could eventually intercept, and (c) Limits of X are used to see if the interception would happened between the provided points (3) Some of the text displayed is the result of using a function called Rational() to convert a number with a decimal into an equivalent P/Q form. Rational() also helps in other ways, especially when printing variables. (4) Some of the code tracks the mouse pointer, which can be helpful in identifying the coordinates of any X-Y point on the graph. The cursor keys, mouse, numeric key pad, A and Z keys, Home, End, and Space Bar all have roles in this program. The space bar, for instance, causes new random lines to be generated. The real advantage of this program is two-fold: (1) You can place different y=f(x) expessions in this program where indicated and see them instantly grafted, which helps in both coding math statements and in learning how different equations actually look when plotted. (2) You have here the option to draw from tables or equations, unlike some programs where you have to approximate functions using freehand and some provided drawing capabilities, such as rectangles, ovals, and bezier curves. | |||||
;TITLE: X-Y 2D Graph ;AUTHOR: Donald R. Darden, oldefoxx@cox.net ;SUBMITTED: June 18, 2003 ;Restrictions: If you use this program as part of your own ;work, give credit where due. You are welcome to adapt the ;included code to other purposes. ;BASIC STRAIGHT LINE EQUATIONS AND RELATIONSHIPS: ;A straight line can be defined a number of different ways: ; (1) Between two points given by (x1,y1) and (x2,y2) ; (2) As a point and slope on the x-intercept (where x=0), ; so that y=Mx+C, where M represents (y2-y1)/(x2-x1) ; (the tangent) of the angle formed, and C represents ; a constant offset along the Y-axis ; (3) A more general equation in the form of Ay+Bx+C=0, ; which avoids the possibility of a division-by-zero ; error with (2) ; (4) A modification of (3) in the form of (y1-y)*(x2-x1)+ ; (y2-y1)*(x-x1)=0, where X and Y are not known, but a ; formula for them can be derived by replacing the ; other unknowns with the x- and y- coordinate date ; for the two points. ; (5) Using Polar Coordinates ;We are using (4) above to work out the equations for the ;lines, but we don't worry about using the "=0". We don't ;know what either X or Y is, but we use variables for each ;of these, while we assign the actual known values for x1, ;y1,x2, and y2, and then solve to ger values for A, B, and ;C in the equation Ax+By+C. Once we have both equations, ;we assume they probably intersect at some point (unless ;they are parallel), and by solving for two simultaneous ;equations, we can get a value for X and for Y which ;defines the point where they intersect, if there is one. ;Computers are better suited to solving complex equations ;if they can be properly expressed, than humans are. In ;fact, rules such as substitution, elimination, or just ;plotting two lines to visually identify where they might ;intersect, are adaptations that fit human capabilities, ;not those of machines. With computers, you are generally ;better off working on a point-by-point basis, from tables ;or arrays, from matrixes, or according to some cardinal ;rule. In our case, there is a relationship called ;Cramer's Rule, which was derived from matrix arithmetic. ;This rule allows the computer to cleanly derive the ;intersection point of two straight lines from their ;equations. The only pitfall is again, the risk of trying ;to divide-by-zero, so the program has to check for this ;possibility and react accordingly. ;The slope form can be handy for determining the relative ;angles of two straight lines to the vertical axis, and ;hence to each other. If the slopes are the same, the two ;lines are parallel, and will never meet. Otherwise, if ;extended, the lines will intersect. If the product of the ;two slopes equals -1 (that is. M1*M2=-1 as found from (2) ;above), then the two lines are exactly perpendicular to ;each other, and the intersection will form right angles ;where the lines intersect. ;Not only does the property M1*M2=-1 tell us that two lines ;are at right angles to each other, but we can determine ;an equation for any point to any line by first finding the ;inverted slope that the constructed line between the point ;and the line should have: It would be the reciprocal of ; of M1, or m2=1/M1. The distance formula between two end ;points is simply D=Sqr((x2-x1)^2+(y2-y1)^2), or for ;better computational speed: ; xd=x2-x1 ; yd=y2-y1 ; D=Sqr(xd*xd+yd*yd) ;Assuming that two points do not just uniquely identify a ;line that could be extended indefinately, but that they ;identify the end points of that line, then the general ;solution using Cramer's Rule has to be refined further. ;IF there is a solution to Cramer's Rule, then we still ;have to prove that the solved-for intersection point of (X,Y) lies between the end points of both lines. ;Fortunately, since there is a unique Y for every X in any ;straight line, we only have to establish the the X lies ;between X1 and X2 of the end points (x1,y1,x2,y2) for the ;line, and the same for the second line, or make sure that ;Y fits between the Y end point values for both lines. It ;isn't necessary to check both for an X-fit and a Y-fit, ;which saves some work. Global xmin=-30 ;lowest value for x to be graphed Global xmax=30 ;highest value for x to be graphed Global scale#=5 ;scale the resulting plot by some factor Global wmax=4620 ;rightmost viewable window pixel reference Global hmax=4620 ;bottommost viewable window pixel reference Global wmin=0 ;leftmost viewable window pixel reference Global hmin=0 ;topmost viewable window pixel reference Global wmid=(wmin+wmax)/2 ;center of viewable area horizontally Global hmid=(hmin+hmax)/2 ;center of viewable area vertically Global zoom=10 ;magnifier for windows viewpoint Global grid=1 ;distance of displayed grid marks Global width0=0 Global height0=0 Global width=800 ;number of pixels horizontally Global height=600 ;number of pixels vertically Global width2=width/2 Global height2=height/2 Global woffset=width2 ;viewpoint width offset, all factors included Global hoffset=height2 ;viewpoint height offset, all factors included Global showscale=0 ;toggles bottom and right scale display Global debug=0 ;real handy if you set debug=1, and ;write "if debug then print ..." ;statements when trying to isolate ;program errors. Global q$=Chr$(34) Dim oxpos(20) ;saves old x position of text writes Dim oypos(20) ;saves old y position of text writes Dim osome$(20) ;saves old text write messages Dim pn$(3) ;saves prime numbers for later reduction Dim pr(3) ;saves numbers for later prime reduction Dim ea$(3) ;saves equations being reduced Dim gp#(2,7) ;Line (x1,y1,x2,y2),a,b,c of expression Ax+by=C Dim eqn$(2) Global ap ;index for gp(ap,n) points Global pr7$="" ;collects prime values in number Global pr4$="" ;collects prime values in number Global x1#,y1#,x2#,y2#,x3#,y3#,x4#,y4#,e1$,e2$,e3$,xn#,yn# Graphics width,height,16,2 ;pick your windows size and colors SetBuffer BackBuffer() ;do plotting out of sight SeedRnd MilliSecs() owoffset=woffset ohoffset=hoffset ozoom=zoom Flip Cls if debug then ;an example of using debug print "Debug mode is currently enabled." print "Press any key to continue." waitkey() endif Goto startdraw ;jump in and calculate initial values While Not KeyHit(1) ;loop until Esc key pressed If KeyDown(30) Or KeyDown(78) Then ;"A" or "+" zoom in If zoom<1000 Then zoom=zoom+1+zoom/50 Goto redraw EndIf EndIf If KeyDown(44) Or KeyDown(74) Then ;"Z" or "-" zoom out If zoom>1 Then zoom=zoom-1-zoom/50 Goto redraw EndIf EndIf If KeyDown(75) Or KeyDown(203) Or KeyDown(219) Then ;left arrow (offset right) woffset=woffset+10 Goto redraw EndIf If KeyHit(31) Then ;"S" show/hide scales at bottom and right side showscale=Not showscale Goto redraw EndIf If KeyDown(71) Then ;left and up (offset down & right) woffset=woffset+10 hoffset=hoffset+10 Goto redraw EndIf If KeyDown(72) Or KeyDown(200) Then ;up arrow (offset down) hoffset=hoffset+10 Goto redraw EndIf If KeyDown(73) Then ;up and right (offset down and left) woffset=woffset-10 hoffset=hoffset+10 Goto redraw EndIf If KeyDown(77) Or KeyDown(205) Or KeyDown(220) Then ;right woffset=woffset-10 Goto redraw EndIf If KeyDown(79) Then ;down and left (offset up and right) woffset=woffset+10 hoffset=hoffset-10 Goto redraw EndIf If KeyDown(81) Then ;down and right (offset up and left) woffset=woffset-10 hoffset=hoffset-10 Goto redraw EndIf If KeyDown(80) Or KeyDown(208) Then ;down (offset up) hoffset=hoffset-10 Goto redraw EndIf If KeyHit(57) Then .startdraw x1=Rnd(xmin,xmax) y1=Rnd(xmin,xmax) x2=Rnd(xmin,xmax) y2=Rnd(xmin,xmax) x3=Rnd(xmin,xmax) y3=Rnd(xmin,xmax) x4=Rnd(xmin,xmax) y4=Rnd(xmin,xmax) Goto redraw EndIf If KeyHit(199) Then ;home key (toggle with previous home setting) h=woffset woffset=owoffset owoffset=h h=hoffset hoffset=ohoffset ohoffset=h h=zoom zoom=ozoom ozoom=h Goto redraw EndIf If KeyDown(207) Then ;end key (set previous home setting to current) owoffset=woffset ohoffset=hoffset ozoom=zoom EndIf mxs=MouseXSpeed() ;get the mouse x position mys=MouseYSpeed() ;get the mouse y position If MouseDown(1) ;check for mouse left button down woffset=woffset+mxs ;if mouse, update width offset hoffset=hoffset+mys ;if mouse, update height offset .redraw ;perform screen redraws when necessary Cls drawgraph() ;first, we redraw the grid view in the window ;-------MODIFY THE FOLLOWING SECTION FOR WHATEVER EQUATIONS(S) YOU WANT TO PLOT------- ;TEST DATA FOR CREATING EQUATION DERIVITIVE PROCESS: ;(y-y1)*(x2-x1)-(x-x1)*(y2-y1) ;the expression for line 1 ;(y-y3)*(x3-x3)-(x-x3)*(y4-y3) ;the expression for line 2 ;first set of test values: ap=1 ; x1#=1:y1#=1:x2#=5:y2#=-1 ;this is test data for 1st line e1$=line_exp(x1#,y1#,x2#,y2#) ;should give us 2y+x-3 ;place first line segment on the screen... Color 255,255,0 n$="Line ("+sout(x1,2)+","+sout(y1,2)+")...("+sout(x2,2)+","+sout(y2,2)+")" Text width2+8,1,n$ Line x1*zoom+woffset,hoffset-y1*zoom,x2*zoom+woffset,hoffset-y2*zoom ;generate first equation and print on screen: Text width2-Len(e1)*8-8,1,e1 ;write to screen ;second set of test values: ap=2 ; x3#=2:y3#=1:x4#=3:y4#=-3 ;this is test data for 2nd line e2$=line_exp(x3#,y3#,x4#,y4#) ;should give us y+4x-9 ;place second line segment on the screen... Color 0,255,255 n$="Line ("+sout(x3,2)+","+sout(y3,2)+")...("+sout(x4,2)+","+sout(y4,2)+")" Text width2+8,15,n$ Line x3*zoom+woffset,hoffset-y3*zoom,x4*zoom+woffset,hoffset-y4*zoom ;generate second equation and print on screen: Text width2-Len(e2)*8-8,15,e2 ;write to screen ;relate the two Line segments To Each other... e3$=cramer$(1,2) Text width2+8,29,"Intercept at ("+e3$+")" ;-----------------------END OF SECTION FOR EQUATION PLOTTING-------------------------- Flip Goto redraw1 ;finish redrawing text EndIf xpos=(MouseX()-woffset)/zoom ypos=(hoffset-MouseY())/zoom .redraw1 ;redraw text when necessary n$="("+xpos+","+ypos+") " ;put mouse coordinates into n$ If n$<>n1$ Then n1$=n$ Color 255,255,255 show width0,height0,n$ EndIf Wend Function show(sxpos,sypos,some$) For os=1 To 20 If oxpos(os)=sxpos And oypos(os)=sypos Then Viewport sxpos,sypos,sxpos+Len(osome$(os))*7,sypos+13 Cls Goto skipout EndIf Next For os=1 To 19 oxpos(os)=oxpos(os+1) oypos(os)=oypos(os+1) osome$(os)=osome$(os+1) Next .skipout Viewport sxpos,sypos,sxpos+Len(some$)*7,sypos+13 Cls Viewport width0,height0,width,height Locate sxpos,sypos Write some$ oxpos(os)=sxpos oypos(os)=sypos osome$(os)=some$ End Function Function swap (u1#,u2#) u3#=u1# u1#=u2# u2#=u3# End Function Function sout$(value#,pos) sout_a=10^pos sout_b$=Int(Abs(value#*sout_a)+.5) If Len(sout_b)<=pos Then sout_b=Right$(String$("0",pos)+sout_b,pos+1) sout_b=Left$(sout_b,Len(sout_b)-pos)+"."+Right$(sout_b,pos) If value#<0 Then sout_b="-"+sout_b Return sout_b End Function Function drawgraph() sizing=grid*zoom ;set the side of the area to be drawn Color 50,50,50 ;make the gridlines a low level grey color x=woffset Mod sizing ;determine the offset for the first grid line While x<=wmax ;create all vertical grid lines Line x,hmin,x,hmax x=x+sizing Wend y=hoffset Mod sizing ;determine the offset for the first grid line While y<=hmax ;create all horizontal grid lines Line wmin,y,wmax,y y=y+sizing Wend If showscale Then ;determine if the scales are to be drawn j#=sizing*5 ;scale lines are every fifth grid line Color 255,255,255 Line width0,height-35,width,height-35 ;the horizontal scale line along the bottom k#=woffset ;work from the grid center backwards i=0 While k#>=width0 ;continue while display area remains If h#<=width Then ;don;t display if still out of view area Line k#,height-45,k#,height-35 ;make a tick mark on the horizontal scale line Locate k#-5,height-35 ;position to write the tick mark value Write Str$(i) ;write the tick mark value EndIf k#=k#-j# ;decrement the amount to the next tick mark i=i-10 ;decrement the tick count by ten Wend k#=woffset+j# ;start at the tick position right of center i=10 ;start with a tick count of ten While k#<=width ;continue across the viewable area If k#>=width0 Then ;don;t bother with line if out of viewable area Line k#,height-45,k#,height-35 ;draw the tick mark indicated Locate k#-5,height-35 ;position to write the tick mark value Write Str$(i) ;write the tick mark value EndIf k#=k#+j# ;increment the tick mark offset position i=i+10 ;increment the tick mark count by 10 Wend Line width-20,height0+20,width-20,height-35 ;draw the right side vertical scale line k#=hoffset ;begin at the center crosshairs i=0 ;set the tick count to zero While k#>=height0+30 ;don;t mess up the equation text area If k#<height Then ;don;t draw line if not in viewable area Line width-35,k#,width-20,k# ;draw a tick mark against the vertical scale line n$=Str$(i) ;create the text for the tick count value Locate width-Len(n$)*8+5*(i<0),k#-5 ;position to write the tick count value Write n$ ;write the tick count value EndIf k#=k#-j# ;decrement the tick mark offset position i=i-10 ;decrement the tick mark count by 10 Wend k#=hoffset+j# ;start at one tick mark below crosshairs i=10 ;start with a count of ten While k#<=height-30 ;continue until out of viewable area If k#>=height0 Then ;delay line if not yet in viewable area Line width-35,k#,width-20,k# ;draw tick mark up to vertical scale line n$=Str$(i) ;get tick mark count Locate width-Len(n$)*8+5,k#-5 ;position to write tick mark count Write Str$(i) ;write tick mark count EndIf k#=k#+j# ;increment tick mark position i=i+10 ;increment tick mark count by 10 Wend EndIf xlen=1000*zoom ;we arbitrarily make the cross hairs 1000 long Color 128,255,128 ;make the crosshairs the color of green Line woffset-xlen,hoffset,woffset+xlen,hoffset ;paint the horizontal crosshair first Line woffset,hoffset-xlen,woffset,hoffset+xlen ;paint the vertical crosshair second Color 255,255,255 ;set the current color to bright white End Function Function reduce$(expression$) equation$=expression ai=1 bi=0 While ai<=Len(equation) Select Mid$(equation,ai,1) Case " " equation=Left$(equation,ai-1)+Mid$(equation,ai+1) Case Chr$(9) equation=Left$(equation,ai-1)+Mid$(equation,ai+1) Case "+" If bi Then equation=Left$(equation,ai-1)+"-"+Mid$(equation,ai+1) ai=ai+1 Case "-" If bi Then equation=Left$(equation,ai-1)+"+"+Mid$(equation,ai+1) ai=ai+1 Case "=" bi=1 equation=Left$(equation,ai-1)+"-"+Mid$(equation,ai+1) ai=ai+1 Default ai=ai+1 End Select Wend While ai ai=Instr(equation,"++") If ai=0 Then ai=Instr(equation,"--") If ai Then equation=Left$(equation,ai-1)+"+"+Mid$(equation,ai+2) Else ai=Instr(equation,"+-") If ai=0 Then ai=Instr(equation,"-+") If ai Then equation=Left$(equation,ai-1)+"-"+Mid$(equation,ai+2) EndIf EndIf Wend ai=Instr(equation,"y") bi=Instr(equation,"x") ci=Instr(equation,"c") If ci=0 Then ci=Len(equation)+1 di=1 While di If ai>bi Then di=ai ai=bi bi=di ElseIf ai>ci Then di=ai ai=ci ci=di ElseIf bi>ci Then di=bi bi=ci ci=bi Else di=0 EndIf Wend If ai Then aj$=Left$(equation,ai) Else aj="" EndIf placeit(aj) If bi Then aj=Mid$(equation,ai+1,bi-ai) Else aj="" EndIf placeit(aj) If ci Then aj=Mid$(equation,bi+1,ci-bi+1) Else aj="" EndIf placeit(aj) For ai=1 To 3 aj=val(ea(ai)) If Instr(aj,".") Then aj=rational(aj,2) pn$(ai)=prime$(aj) aj=ea(ai) bi=Instr(aj,"/") If bi Then aj=Mid$(aj,bi) Else aj=Right$(aj,1) Select aj Case "x" Case "y" Default aj="" End Select EndIf ea(ai)=aj Next For ai=1 To 2 aj=pn(ai) If aj="*0*" Then Goto chk_next2 bi=1 While bi ci=Instr(aj,"*",bi+1) If ci Then bj$=Mid$(aj,bi,ci-bi+1) For di=ai+1 To 3 cj$=pn(di) ei=Instr(cj,bj) If ei=0 And cj<>"*0*" Then Goto chk_next1 Next For di=1 To 3 cj$=pn(di) ci=Instr(cj,bj) If ci Then cj=Left$(cj,ci)+Mid$(cj,ci+Len(bj)) If cj="*" Then cj="*1*" pn(di)=cj EndIf Next ci=bi EndIf .chk_next1 bi=ci Wend .chk_next2 Next For ai=1 To 3 aj=pn(ai) bi=1 ci=1 While ci di=Instr(aj,"*",ci+1) If di Then bi=bi*val(Mid$(aj,ci+1)) ci=di Wend pr(ai)=bi cj=ea(ai) If ai>1 Then If bi>0 Then bj=bj+"+" ElseIf bi=0 And cj>"" Then bj=bj+"+" EndIf bj=bj+bi+cj Else bj=bi+cj EndIf Next Return bj End Function Function placeit(eax$) Select Right$(eax,1) Case "y" eay=1 Case "x" eay=2 Default eay=3 End Select ea$(eay)=eax Return eay End Function Function line_exp$(xa#,ya#,xb#,yb#) u1#=ya#-yb# u2#=xb#-xa# u3#=u2*ya+u1*xa If Abs(u1)>1 Then le$=prime$(u1) ElseIf Abs(u2)>1 Then le$=prime$(u2) Else le$=prime$(u3) EndIf s1=1 While s1 s2=Instr(le,"*",s1+1) If s2 Then s3=val(Mid$(le,s1+1)) If s3>1 Then If (u1 Mod s3)=0 And (u2 Mod s3)=0 And (u3 Mod s3)=0 Then u1=u1/s3 u2=u2/s3 u3=u3/s3 EndIf EndIf EndIf s1=s2 Wend gp(ap,1)=xa gp(ap,2)=ya gp(ap,3)=xb gp(ap,4)=yb gp(ap,5)=u1 gp(ap,6)=u2 gp(ap,7)=u3 le$=rational(u1,2)+"x+"+rational(u2,2)+"y+"+rational(-u3,2) s1=1 While s1 s1=Instr(le,"-+") If s1=0 Then s1=Instr(le,"+-") If s1 Then le=Left$(le,s1-1)+"-"+Mid$(le,s1+2) Wend s1=1 While s1 s1=Instr(le,"--") If s1=0 Then s1=Instr(le,"++") If s1 Then le=Left$(le,s1-1)+"+"+Mid$(le,s1+2) Wend eqn(ap)=le s1=1 While s1 s1=Instr(le,"+0") If s1=0 Then s1=Instr(le,"-0") If s1 Then Select Mid$(le,s1+2,1) Case "y", "x" le=Left$(le,s1-1)+Mid$(le,s1+3) Default le=Left$(le,s1-1)+Mid$(le,s1+2) End Select EndIf Wend Return le End Function Function rational$(value#,pos) places = 10^pos r4# = -1 r1#=value-Int(value) If Int(r1*places+.5)=0 Then pp$=value Goto not_rational EndIf r1# = 1/value r5# = 1 r6# = 1 r0 = 8 Repeat r0=r0-1 If r0=0 Then Goto abort r5 = r1*r5 r2# = 1/r1 r1 = r2-Int(r2) If r1 = 0 Then r1 = 1 r3# = r2/r1 r5 = r5*r3 r4 = Int(r5) r7# = Int(r4*value) pr7$=prime$(r7) an=1 While an ;eliminate matching primes from numerator and denominator bn=Instr(pr7,"*",an+1) If bn Then s1=val(Mid$(pr7,an+1)) If s1 Then If r4 Mod s1=0 Then r7=r7/s1 r4=r4/s1 EndIf EndIf EndIf an=bn Wend r6=r7/r4-value Until Int(r6#*places)=0 .abort If r4<0 Then r7=-r7 r4=-r4 EndIf If r4>1 Then pp=r7 s1=Instr(pp,".") If s1 Then pp=Left$(pp,s1-1) pp=pp+"/"+r4 Else pp=r7 EndIf .not_rational s1=Instr(pp,".") If s1 Then pp=Left$(pp,s1-1) Return pp End Function Function val#(some$) ab#=some$ Return ab End Function Function prime$(number#) ad=Int(Abs(number)) at$="*" bd=1 cd=Sqr(ad) dd=2 While dd<=cd If (ad Mod dd)=0 Then ad=ad/dd at=at+dd+"*" Else dd=dd+bd bd=2 EndIf Wend If number#<0 Then at="*-1"+at If ad>1 Then at=at+ad+"*" Return at End Function Function Cramer$(n1,n2) div#=gp(n1,5)*gp(n2,6)-gp(n2,5)*gp(n1,6) If div Then div=1/div Else div=10*20 EndIf xn#=(gp(n1,7)*gp(n2,6)-gp(n2,7)*gp(n1,6))*div yn#=(gp(n2,7)*gp(n1,5)-gp(n1,7)*gp(n2,5))*div ;The following code restricts intersections to areas between points If xn>=gp(n1,1) And xn<=gp(n1,3) Then ;possible intersection along first line ElseIf xn<=gp(n1,1) And xn>=gp(n1,3) Then ;possible intersection along first line Else Goto nointersection EndIf If xn>=gp(n2,1) And xn<=gp(n2,3) Then ;possible intersection along second line ElseIf xn<=gp(n2,1) And xn>=gp(n2,3) Then ;possible intersection along second line Else .nointersection Return "---,---" EndIf ;End of code for restriction interesctions to areas between points le$=rational(xn,2) p1=le$ s1=Instr(le,"/") If s1 Then q1=val(Mid$(le,s1+1)) r1=Int(p1/q1) p1=P1-r1*q1 Else r1=0 q1=0 EndIf le=rational(yn,2) p2=le$ s1=Instr(le,"/") If s1 Then q2=val(Mid$(le,s1+1)) r2=Int(p2/q2) p2=p2-r2*q2 Else r2=0 q2=0 End If If r1 Then le=r1 s1=Instr(le,".") If s1 Then le=Left$(le,s1-1) le=le+" " Else le="" EndIf le=le+p1 s1=Instr(le,".") If s1 Then le=Left$(le,s1-1) If q1>1 Then le=le+"/"+q1 s1=Instr(le,".") If s1 Then le=Left$(le,s1-1) EndIf le=le+"," If r2 Then le=le+r2 s1=Instr(le,".") If s1 Then le=Left$(le,s1-1) le=le+" " EndIf le=le+p2 s1=Instr(le,".") If s1 Then le=Left$(le,s1-1) If q2>1 Then le=le+"/"+q2 s1=Instr(le,".") If s1 Then le=Left$(le,s1-1) EndIf Return le End Function |
Comments
None.
Code Archives Forum