View Single Post
 
Old 09-16-2013, 08:03 PM
BobBridges's Avatar
BobBridges BobBridges is offline Windows 7 64bit Office 2010 32bit
Expert
 
Join Date: May 2013
Location: USA
Posts: 700
BobBridges has a spectacular aura aboutBobBridges has a spectacular aura about
Default

Ok, I see the problem. I was staring at it suspiciously for quite a while, but I couldn't figure out exactly what it did so I wasn't sure it was wrong. I had to run the thing interactively to pin it down; and that's how you're going to do it, too.

Go to the Excel VBA editor, put the cursor on the first line of the program (the one that says "Sub SatData()"), and hit <F9>. Notice how that line turns sort of burgandy; it means you've put a "break" or "breakpoint" on that line; that means when your program gets to that point in the execution, it'll stop and call for your attention. Now go back to the Saturdays worksheet and start the macro.

Immediately you're back in the macro editor again, looking at that line—only now it's highlighted in yellow. That means the program is running, and it's about to run that statement.

Now hit <F8> just once, and watch the yellow highlighting advance. It jumps over the Dim statements to the first ClearContents command. That's the statement it's about to execute in the VBA program. <F8> is a command to the editor to execute just one statement in your program, and then to pause again.

Hit <F8> again and it'll jump to the next statement. If you pause at this point and go look at your "Print Out" worksheet, you'll notice that the contents of Y1:Z500 are indeed now cleared.

Hit <F8> again, several times, one at a time—feel free to watch the results in the worksheet—until you get to the InputBox function. When you hit <F8> on that one, the input box will be displayed on your screen. Go ahead and enter the desired date—2013-06-22, it was, in this case.

Now, back in the VBA editor, the Cells.Find statement is highlighted. Before you hit <F8> again, cause your mouse arrow to hover over a few items in your program:

Put the cursor over SatDate—any instance of SatDate in your program, it doesn't matter which one. A little box will pop up showing the current value of SatDate (presumably "2013-06-22", just now). Have the cursor hover over the variable a few lines down that you named y; just now it'll say it's "Empty", because you haven't yet set it to anything. Hover over ActiveCell.Value a few lines further down yet; on my machine just now it says "Business Name", because the active cell is currently A1. Feel free to explore a little.

When you're ready, hit <F8>; the program has now done the search for the date you typed in. If you go back to the worksheet, you'll see that that date is now selected in row 1. But when you go back to the VBA editor and hit <F8> again, the next statement is executed, which in your worksheet moves the selection down one row.

We're almost to the problem. Go ahead and step down through "y = 8" (and now y isn't Empty any more), the For loop, the If statement, and so on until you get to "Range("'Print Out'!Y" & y) = Cells(y, 2)". Here we'll stop and discuss a moment.

The variable y is the row number for the output on the Print Out worksheet. Your program has already set 'Print Out'!Z8 to the dollar value (you can go and check, if you like). Now the next statement is supposed to set 'Print Out'!Y8 to the name (in column B, ie 2) from the input row on the Saturdays sheet.

But wait—that may be what you want it to do, but it isn't what you told it to do. You told it to use the value not from that row but from Cells(y,2). Hover your mouse over "Cells(y, 2)", and you'll see that it displays the wrong name, "Bishop, Derrick", not "Anders, Nelli" as it should.

Why? Cells(y, 2) says to pull from row y, column 2; and since y = 8, you pulled it from the Saturdays worksheet, row 8, column 2. Right column, wrong row; y is the variable you're using for your output row.

How to tell your program which input row to use? Well, I don't think much of using ActiveCell and moving it around; most people say that slows your program down unnecessarily. If we keep this up together, I'd just as soon show you some better ways. But for now, since you're already using ActiveCell, just to keep it simple you could do it this way:
Code:
Range("'Print Out'!Z" & y) = ActiveCell.Value
row = ActiveCell.Row
Range("'Print Out'!Y" & y) = Cells(row, 2)
Or you could combine it this way:
Code:
Range("'Print Out'!Z" & y) = ActiveCell.Value
Range("'Print Out'!Y" & y) = Cells(ActiveCell.Row, 2)
I haven't tested that, but unless I made a typo it should work.

...But there are some other problems with this program that I'd like to talk about, aside from the obvious bug. These are not exactly wrong, but there are ways to make it easier to run:

1) Rather than have the user type in the desired date (and risk it being typed in wrong, or using the wrong format), it seems to me it's easier on the user to point to the correct column just by putting using the arrow keys to put the selection somewhere in that column. That also enables you to dump the concept of having two different programs; just use whichever worksheet the user points to.

2) Rather than telling your program which rows to look at (1 to 104 for Wed, 1 to 179 for Sat), have your program find the right ending row by itself. That way you don't have to keep adjusting it whenever you add enough new shops to the worksheets.

There are a few other things but they're relatively minor and they'll probably come to you anyway, after a little more practice. But these two will be significant improvements in ease of use and of programming.
Reply With Quote