28.

Task Four: Appending to the Database

Now that you've added monthly dates to the imported Nov2002 worksheet, it has the same columns as the order-history database, so you can just copy the worksheet and append it to the first blank row below the database. Of course, you don't want to include the column headings.

Append a Worksheet to a Database

First you'll copy the data (without the headings) from the Nov2002 worksheet. Then you'll open the database, select the first blank cell below the database, rename the database range to include the new rows, and close the database file.

Record Macro

  1. Select one of the Nov2002 worksheets that has the labels filled and the dates added, click the Record Macro button, type AppendDatabase as the macro name, and then click OK.

  2. Select cell A1. Choose the Edit menu, click Delete, click the Entire Row option, and click OK.

    This deletes the heading row so that you won't include it in the range you copy to the database.

  3. Press Ctrl+Shift+* to select the current region, and then click Copy on the Edit menu.

    Open

  4. On the toolbar, click the Open button, type  Orders.dbf in the File Name box, and click Open.

    The  Orders.dbf database file opens with cell A1 selected. The values in column A appear as number signs because the column is too narrow to display the dates.

  5. In the column headings, double-click the border between columns A and B to adjust the width of the Date column. (The dates in the database look different than those in Nov2002 because of formatting differences.)

  6. Press Ctrl+Down Arrow to go to the last row of the database.

  7. Press the Down Arrow key to select the first cell below the database. (It should be cell A3301.)

    click to expand

  8. Choose the Edit menu, click Paste to append the rows you previously copied, and then press the Esc key to remove the copy message from the status bar.

    click to expand

  9. Press Ctrl+Shift+* to select the entire new database range, including the newly appended rows.

    Important  

    When you open a dBase file in Excel, the range containing the actual database records is automatically named Database. When you save the updated  Orders.dbf file as a dBase file, only the values within the range named Database are saved. Any other cell values in the file are discarded. To have the new rows saved with the file, you must enlarge the Database range definition to include them.

  10. Choose the Insert menu, choose the Name submenu, and click the Define command. Type Database in the Names In Workbook box, and then click OK.

    Important 

    Don't select Database from the list of names. If you do, the range the name refers to will remain unchanged.

    click to expand

    Now the entire database, including the new rows, is included in the Database range name and will be saved with the file.

  11. Choose the File menu, click Close, and then click No when asked whether you want to save changes. For now, you don't want to save the database with the new records to the  Orders.dbf file because you want to first test the macro.

    Stop Recording

  12. Select cell A1, and then click the Stop Recording button to turn off the recorder.

Step Through the AppendDatabase Macro

Step through the macro to see it work, and note any changes you should make.

  1. Activate a worksheet with the labels filled in and the dates added. (Run the ImportFile, FillLabels, and AddDates macros if necessary.)

    Run Macro

  2. Click the Run Macro button, select the AppendDatabase macro, and click the Step Into button. Look at the first five lines of the macro:

    Sub AppendDatabase()     Range("A1").Select     Selection.EntireRow.Delete     Selection.CurrentRegion.Select     Selection.Copy

    These statements are similar to statements you've seen in earlier macros.

  3. Press F8 five times to execute the first five statements in the macro. In the Visual Basic window, the statement that opens the database should be highlighted:

    Workbooks.Open Filename:="C:\ExcelVBA\Orders.dbf"

    This statement opens the database.

    Tip 

    If you remove everything except  Orders.dbf from the file name, the macro looks for the file in the current folder. That would be useful if you move the project to a new folder.

  4. Press F8 to execute the statement containing the Open method and move to the next statement:

    Columns("A:A").EntireColumn.AutoFit

    This statement makes column A wide enough to show all the values.

  5. Press F8 to resize the column and move to the next statement:

    Selection.End(xlDown).Select

    This statement is equivalent to pressing Ctrl+Down Arrow. It starts with the active cell, searches down to the last nonblank cell, and selects that cell.

  6. Press F8 to select the last cell in the database and move to the next statement:

    Range("A3301").Select

    This statement selects cell A3301. That is the first cell below the database this month, but next month it will be wrong. This is the statement the recorder created when you pressed the Down Arrow key. What you wanted was a statement that moves one cell down from the active cell. You'll need to fix this statement. Make a note to do so.

  7. Press F8 to select cell A3301 and move to the next statement. The next two statements work together:

    ActiveSheet.PasteApplication.CutCopyMode = False

    These statements paste the new rows into the database and remove the status bar message.

  8. Press F8 twice. The next two statements redefine the Database range:

    Selection.CurrentRegion.Select ActiveWorkbook.Names.Add Name:="Database", RefersToR1C1:= _     "=Orders!R1C1:R3478C7"

    The first statement selects the current region, which is the correct range for the new database range. The second statement gives the name Database to the specific range R1C1:R3478C7 (A1:G3478). This isn't what you want. You want the name Database to be assigned to whatever selection is current at the time the statement executes. You'll also need to fix this statement. Make a note to do so.

  9. Press F8 twice to move to the statement that closes the workbook file:

    ActiveWorkbook.Close

    This statement closes the active workbook. If you've made changes to the workbook, it also prompts you to save the changes. You can program the macro to always save changes or (while testing) to never save changes. (See the 'Choose Whether to Save Changes While Closing a File' section later in this chapter.)

  10. Press F8 to close the database workbook. Click No when asked whether you want to save changes. Only two statements remain in the macro:

    Range("A1").SelectEnd Sub
  11. Press F8 twice to end the macro.

The macro works now only because you're running it under circumstances identical to those when you recorded it, with the same current month file and the same database file. Here's a recap of the changes you'll need to make:

  • Select the first row under the database.

  • Give the name Database to the current selection.

  • Don't prompt when closing the database.

Record a Relative Movement

Take a closer look at the two statements in AppendDatabase that find the first blank cell under the database. Imagine what will happen when you run this next month, when the database has more rows. The statement

Selection.End(xlDown).Select

will select the bottom row, but then the statement

Range("A3301").Select

will always select the absolute cell A3301 anyway.

When you select a cell, the macro recorder doesn't know whether you want the absolute cell you selected or a cell relative to where you started. For example, when you select a cell in row 1 to change the label of a column title, you always want the same absolute cell, without regard to where you started. But when you select the first blank cell at the bottom of a database, you want the macro to select a cell relative to where you started.

The macro recorder can't automatically know whether you want to record absolute cell addresses or relative movements, but you can tell the recorder which kind of selection you want. Use the recorder to record a new statement that you can use to replace the offending statement. You'll record the new statement in a new, temporary macro, and then copy the statement and delete the temporary macro.

  1. Click the Record Macro button, type TempMacro as the macro name, and click OK.

    Relative Reference

  2. On the Stop Recording toolbar, click the Relative Reference button.

    When this button is activated, the recorder makes all new cell selections relative to the original selection. Now you need to replace the statement that selects cell A3301 with one that makes a relative movement.

    You want to record the action of moving down one cell so that you can record the macro from any cell, on any worksheet.

  3. Press the Down Arrow key once to record a relative movement.

    Stop Recording

  4. Click the Relative Reference button to deselect it, and then click the Stop Recording button.

  5. Edit the TempMacro macro and look at the change. The new statement you recorded should look like this:

    ActiveCell.Offset(1,0).Range("A1").Select

    This statement means, 'Select the cell below the active cell.' It really does. At this point, you don't need to understand everything about how this statement works. Just trust the recorder. But you might wonder why the statement includes the words Range("A1") when it has nothing to do with cell A1. This statement calculates a new single-cell range shifted down one cell from the original active cell. The macro treats that new range as if it were the upper left corner of an entire 'virtual' worksheet and selects cell A1 of that imaginary worksheet!

  6. Select the new statement, and copy it.

  7. Open the Procedure drop-down list (below the toolbars on the right side of the Module window), and select AppendDatabase.

  8. Select Range("A3301").Select, delete it, and paste the new statement in its place.

  9. Select the TempMacro macro from the Procedure drop-down list.

  10. Delete the TempMacro macro by first selecting all the statements from Sub TempMacro to End Sub and then pressing the Delete key.

With the Relative Reference button, you can control whether selections are absolute or relative to the current active cell. You can turn the Relative Reference button on and off as many times as you need while you're recording a macro.

Name the Current Selection

The statement in the AppendDatabase macro that defines the Database range name contains a potentially serious problem.

ActiveWorkbook.Names.Add Name:="Database", RefersToR1C1:= _     "=Orders!R1C1:R3478C9"

This statement sets the name Database to the range that the database occupies at the end of this month. If you don't change this statement before next month, December orders will be discarded from the database when you save it. This is a case where the macro recorder generates a complicated statement when a simple one would work better.

  1. Delete the entire recorded statement.

  2. In its place, type

    Selection.Name = "Database"

    Name is a property of a range. By simply assigning a word in quotation marks as the value of the Name property, you can name the range.

Choose Whether to Save Changes While Closing a File

The statement that closes the database file looks like this:

ActiveWorkbook.Close

This statement triggers a prompt that asks whether you want to save changes to the file, because you've made changes to it since you opened it. Sometimes when you automate a process, you know that you always will (or won't) want to save changes. The Close method has an optional argument that allows you to specify whether to save changes. For now, while you're testing the macro, set the statement to not save the changes.

  1. Change the statement that closes the workbook to this:

    ActiveWorkbook.Close SaveChanges:=False

    The SaveChanges argument answers the dialog box's question before it even gets asked.

  2. Save the Chapter02 workbook. Then run and test the AppendDatabase macro yourself.

  3. Once you've finished testing the macro and are ready to use it regularly, change the word False to True.

    Tip 

    Technically, since the active workbook happens to be a dBase file, setting the SaveChanges argument to True prevents Excel from asking whether you want to save the changes, but Excel still displays a dialog box to ensure that you want to save the file as a dBase file. If the active workbook is a native Excel workbook, however, the SaveChanges argument causes Excel to save it quietly.

Here's the final version of the AppendDatabase macro:

Sub AppendDatabase()     Range("A1").Select     Selection.EntireRow.Delete     Selection.CurrentRegion.Select     Selection.Copy     Workbooks.Open Filename:="C:\Excel VBA Practice\Orders.dbf"     Columns("A:A").EntireColumn.AutoFit     Selection.End(xlDown).Select     ActiveCell.Offset(1, 0).Range("A1").Select     ActiveSheet.Paste     Application.CutCopyMode = False     Selection.CurrentRegion.Select     Selection.Name = "Database"     ActiveWorkbook.Close SaveChanges:=True     Range("A1").Select End Sub

If you want, you can run the macro again now. It will work the same as it did before, but it's also ready for next month, when the database will have more records.

You're almost finished. The only task left is to get rid of the imported worksheet.



Microsoft Excel 2002 Visual Basic for Applications Step by Step
FrameMaker 6: Beyond the Basics
ISBN: 735613591
EAN: 2147483647
Year: 2005
Pages: 122
Authors: Lisa Jahred

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net