Beruflich Dokumente
Kultur Dokumente
Microsoft provides examples of Visual Basic for Applications procedures for illustration only, without warranty either expressed or implied, including, but not limited to the implied warranties of
merchantability and/or fitness for a particular purpose. The Visual Basic procedures in this workbook are provided 'as is' and Microsoft does not guarantee that they can be used in all situations.
While Microsoft AnswerPoint Engineers can help explain the functionality of a particular macro, they will not modify these examples to provide added functionality, nor will they help you construct
macros to meet your specific needs. If you have limited programming experience, you may want to consult one of the Microsoft Solution Providers.
Samples
Data Access
Office Automation
Event Handling
Page 3
Worksheet Functions
To use this feature, select a cell within the data range that you
would like to use, then select Tools / Wizard / Lookup, and follow
the steps in the wizard.
For additional information, use the assistant and search using the
words "Lookup Wizard".
To use this feature, select a cell within the list that you would like to
summarize, then select Tools / Wizard / Conditional Sum, and
follow the steps in the wizard. Page 4
For additional information, use the assistant and search using the
words "Conditional Sum".
Another common task in Excel is to calculate Worksheet
the sum of Functions
the values
meeting the conditions you specify. The Conditional Sum Wizard
helps you write formulas that accomplish this task.
To use this feature, select a cell within the list that you would like to
summarize, then select Tools / Wizard / Conditional Sum, and
follow the steps in the wizard.
For additional information, use the assistant and search using the
words "Conditional Sum".
Page 5
Working with Arrays
SUMMARY
The most common way to transfer the contents of an array to a worksheet is through a loop, such
as a For...Next loop. A For...Next loop allows you to index into the array and transfer elements of
the array to their destination address one at a time. You can accomplish this same result without
a loop using the Visual Basic, Applications Edition, FormulaArray property of the Range object.
In Visual Basic, Applications Edition, the orientation of a one-dimensional array is horizontal.
Therefore, if the range of cells on a worksheet that are to receive the contents of an array are also
in the same orientation (that is, one row by several columns), the contents can be transferred with
a single FormulaArray statement. For example:
The two-dimensional array shown in this example allows Visual Basic to set the orientation of the
array as vertical; therefore, the array can be transferred to a worksheet without a loop.
Goto ArrayDump1
Sample Code
Goto ArrayDump2
Sample Code
Repeating Tasks
Often it is necessary to perform the same task on a group of items. These items may be cells in a
range, worksheets in a workbook, workbooks in the Application.
Although the macro recorder cannot record loops, the recorder can still be used to record the main
task to be repeated. Then, with some minor modifications to the recorded code, various types of
loops can be created depending on what is needed for an individual project.
The samples below focus on a scenario where the programmer has a range of cells in column A
containing numbers, and depending on the value of the cell, wishes to change the color of the
corresponding cell in column B.
First, we can record the single step process of changing the color of the background of a cell:
(To record: From the Tools Menu, click Macro, then click Record New Macro)
While recording, from the Format menu, click Cells. Then, click the Patterns tab and select a color.
This sample uses Yellow (.ColorIndex=6). Now stop the recorder using the Stop button on the
Stop Recording Toolbar.
The currently selected cell will change color and the following macro will have been recorded:
Sub Recorded_Macro()
'
' Macro recorded 6/30/97
' Goto Recorded_Macro
With Selection.Interior Sample Code
.ColorIndex = 6
.Pattern = xlSolid
End With
End Sub
Note: If, while recording, you selected a cell, your macro may contain something similar to
Range("A3").Select. You may want to remove this line, since every time the macro is run,
this line will force the cell specified in the Range object to be selected. If you want that cell to be
selected first then leave that line in the macro.
Now, we can modify the code slightly and add one of the various looping structures to the recorded code.
If we know what range of cells to which we want to apply the recorded action, we can use a For Each…Next loop.
In this example, we also want to only affect the cell in column B if the cell in A is greater than 20.
To do this we add an If statement around our recorded With statement. This will ensure the color
will be changed only if the If statement's condition is true.
Lastly, because we are wanting to change the corresponding cell one column to the right of
column A (column B), we will replace the Selection property in the recorded code with the Offset
method of the looping cell object (cell_in_loop).
The resulting code might look like this:
Sub For_Each_Next_Sample()
'
' Macro recorded 6/30/97
'
For Each cell_in_loop In Range("A1:A5")
If cell_in_loop.Value > 20 Then Goto For Each..Next
With cell_in_loop.Offset(0, 1).Interior Sample Code
.ColorIndex = 6
.Pattern = xlSolid
End With
End If
Next
End Sub
For…Next Loop
If you know how many times you wish to loop through your code you can use a For..Next loop.
Using our example, if you want to only check 10 cells down, starting from the selected cell, then
your modified recorded code might look like this:
Sub For_Next_Sample()
For Counter = 0 To 9
If Selection.Offset(Counter, 0).Value > 20 Then
With Selection.Offset(Counter, 1).Interior
.ColorIndex = 6 Goto For..Next Sample
.Pattern = xlSolid Code
End With
End If
Next
End Sub
Here the Selection object is being used so that the code is not specific to any given range, but will
always loop through ten (0 to 9 as a counter) cells below the active cell. The Counter variable
increments each time through the loop and can be used within the looping structure. Here it is
used as an Offset argument to indicate how many rows to offset from Selection (the current cell).
So, if we start this macro and the active cell is A1, the first time through the loop the Counter
variable will equal 0, therefore we will Offset 0 rows from A1 as shown in the
Selection.Offset(Counter, 0).Value statement.
Do…Loop
To determine whether or not to stop a loop based on a certain condition, a Do…Loop might be
appropriate. This looping structure allows you to check properties or variable conditions before the
loop is executed. In the sample below, we continue to loop until the referenced cell's row number,
Selection.Offset(Counter, 0).Row, has exceeded 100. This can be useful if you never
want to perform the looping task below row 100.
Sub Do_Loop_Sample()
Counter = 0
Do Until Selection.Offset(Counter, 0).Row > 100
If Selection.Offset(Counter, 0).Value > 20 Then
With Selection.Offset(Counter, 1).Interior Goto Do…Loop Sample
Code
Goto Do…Loop Sample
.ColorIndex = 6 Code
.Pattern = xlSolid
End With
End If
Counter = Counter + 1
Loop
Note: There are three more types of Do…Loops available. The various forms offer more flexibility
when needed in various circumstances.
To find more information about these, and more detail about the other looping structures, please
access Help from within the Visual Basic Environment and use the keyword looping.
ach…Next loop.
Attaching Labels to an XY (Scatter) Chart
Labels X Values Y Values
Datapoint1 2 5 Place Labels on Reset Chart
Datapoint2 9 7 Chart
Datapoint3 5 3
Datapoint4 4 8
8
Datapoint5 1 4
7.5
7
In Microsoft Excel, there is no built-in way to
automatically attach text labels to an xy 6.5
(scatter) chart. You can use a macro to
accomplish this. 6
This example retrieves data from a dBase file using RDO, and places the recordset in a Query Table on a new worksheet.
Use this method when connecting to SQL databases. RDO bypasses DAO which decreases the overhead in memory.
Sub RDOExample()
Dim ws As Workspace
Dim rs As Recordset
Dim qt As QueryTable
Dim c As Connection
Dim ConnectStr As String
Dim NewSheet As Object
'If Microsoft Office was not installed to the default location,
'change the path to the appropriate folder prior to running the code
ConnectStr = "odbc;Driver={Microsoft dBase Driver (*.dbf)};DBQ=c:\program
files\microsoft office\office;"
'Creates a workspace that bypasses DAO
Set ws = CreateWorkspace("w1", "admin", "", dbUseODBC)
'Opens the connection to the directory containing DBF files
Set c = ws.OpenConnection("", 1, 0, ConnectStr)
'Gets all records from the table, and allows forward movement only
'through the records (fastest type)
Set rs = c.OpenRecordset("select * from orders", dbOpenForwardOnly)
'Insert a new worksheet in the active workbook
Set NewSheet = Worksheets.Add
'Puts a new Query Table based on the recordset on the new sheet
Set qt = NewSheet.QueryTables.Add(rs, Range("a1"))
'Performs a synchronous refresh on the Query Table
qt.Refresh False
'Close the recordset
rs.Close
'Close the connection
c.Close
End Sub
R
Sub ResettingDAORecordset() R
Dim db As Database
Dim rs As Recordset
Dim qt As QueryTable
Dim NewSheet As Object
Dim nwind As String
'Default path to Northwind.mdb sample database
nwind = "C:\Program files\microsoft office\office\samples\Northwind.mdb"
'Opens the Northwind.mdb sample database
Set db = DBEngine.Workspaces(0).OpenDatabase(nwind)
'Opens a recordset containing all records from the customers table
Set rs = db.OpenRecordset("customers")
'Insert a new worksheet in the active workbook
Set NewSheet = Worksheets.Add
'Insert a Query Table containing the recordset information on the new sheet
Set qt = NewSheet.QueryTables.Add(rs, Range("a1"))
Sub RetrieveAccessData()
Dim Nsql As String, Ncriteria As String, Njoin As String
Dim nwind As String
Dim h As Integer
Dim db As Database, qry As Object
Dim rec As Recordset, NewSheet As Object
'Default installation location of Northwind.mdb database
nwind = "C:\Program files\microsoft office\office\samples\Northwind.mdb"
'When an error is encountered go to the label errorhandler:
On Error GoTo errorhandler
'Open database
Set db = DBEngine.Workspaces(0).OpenDatabase(nwind)
'SQL statements for query (copied from MS Query's SQL window)
Nsql = "SELECT DISTINCTROW Categories.CategoryName, Products.ProductName,
Products.QuantityPerUnit, Products.UnitPrice "
Njoin = "FROM Categories INNER JOIN Products ON Categories.CategoryID =
Products.CategoryID "
Ncriteria = "WHERE ((([Products].Discontinued)=No) AND
(([Products].UnitsInStock)>20));"
'Create a query named TempQuery
Set qry = db.CreateQueryDef("TempQuery")
'Send SQL statement to TempQuery
qry.sql = Nsql & Njoin & Ncriteria
'Open the resulting recordset created by TempQuery
Set rec = qry.OpenRecordset()
'Add a new worksheet to the workbook containing this code
Set NewSheet = ThisWorkbook.Sheets.Add(after:=Worksheets("Data Access"),
Type:=xlWorksheet)
'Put field names in row 1 of the new worksheet
For h = 0 To rec.Fields.Count - 1
NewSheet.[a1].Offset(0, h).Value = rec.Fields(h).Name
Next h
'Copy the dynaset to excel
NewSheet.[a2].CopyFromRecordset rec
'Delete temporary query
db.QueryDefs.Delete "TempQuery"
'Close the database
db.Close
'If no errors encountered, stop executing code
Exit Sub
'Error handler to delete the query if it already exists
errorhandler:
If DBEngine.Errors(0).Number = 3012 Then
db.QueryDefs.Delete "TempQuery"
'Begins executing code at the line that caused the error
Resume
Else
MsgBox Error(Err)
End If
End Sub
Sub ListTables()
Dim db As Database, TableCount As Long, i As Long
Dim dPath As String
'Default location of Northwind.mdb
dPath = "C:\Program files\microsoft office\office\samples\Northwind.mdb"
'Open nwind.mdb
Set db = DBEngine.Workspaces(0).OpenDatabase(nwind)
'Set a variable to number of tables
TableCount = db.TableDefs.Count
'Loop through all tables
For i = 0 To TableCount - 1
'Display the table name
MsgBox db.TableDefs(i).Name
Next
'Close the database
db.Close
End Sub
Sub ODBC_Connection()
Dim db As Database, i As Long
'Displays the DSN dialog box allowing the user to select the dsn,
'then prompts for additional information if necessary
Set db = DBEngine.Workspaces(0).OpenDatabase("", , , "ODBC;")
'Count the number of tables
TableCount = db.TableDefs.Count
'Loop to display all table names
For i = 0 To TableCount - 1
MsgBox db.TableDefs(i).Name
Next
'Closes the database
db.Close
End Sub
CREATING A TABLE
This example demonstrates how to create a new table within an existing database. The following example uses the
Northwind sample database installed with Microsoft Access 97.
Sub Create_Table()
Dim t As Object, f As Object, d As Database
Dim dPath As String
'When an error is encountered go to the label errorhandler:
On Error GoTo errorhandler
'Default path for Northwind.mdb sample database
dPath = "C:\Program files\microsoft office\office\samples\Northwind.mdb"
'Open the Northwind database
Set d = DBEngine.Workspaces(0).OpenDatabase(dPath)
'Create new TableDef
Set t = d.CreateTableDef("NewTable")
' Add fields to NewTable.
Set f = t.CreateField("Field1", dbDate)
t.Fields.Append f 'Adds field to the field collection
Set f = t.CreateField("Field2", dbText)
t.Fields.Append f
Set f = t.CreateField("Field3", dbLong)
t.Fields.Append f
' Save TableDef definition by appending it to TableDefs collection.
d.TableDefs.Append t
'Close the database
d.Close
Exit Sub
errorhandler:
MsgBox DBEngine.Errors(0)
End Sub
Goto
GotoRetrieve
RDO Example
Access
Data
Sample
SampleCode
Code
Goto
GotoRetrieve
Resetting
Access
DAO
Recordset
Data Sample
Sample
Code
Code
Goto
GotoRetrieve
Resetting
Access
DAO
Recordset
Data Sample
Sample
Code
Code
Goto
GotoRetrieve
RetrieveAccess
Access
Data
DataSample
SampleCode
Code
Goto Retrieve ISAM Data
Sample Code
Goto List Tables Sample
Code
BeforeDoubleClick
A very popular type of Event is the BeforeDoubleClick event on a worksheet. A very simple
example may look like:
This event will fire whenever the user double clicks a cell in the worksheet. The parameter Target
is passed into the macro so the programmer will know what cell has been double clicked. The
Cancel argument has a default value of False but can be changed to True within the code. Setting
Cancel to True will cancel the default action for the event. In this case, the default action for a
double click on a cell is to switch to edit mode on the cell. Since we set Cancel to True, this will
not occur. If you want to still have the default action occur, then the Cancel=True line can be
removed.
Change
Another very useful event is the Change event for a worksheet. Any time the user enters a new
value in any cell this event fires.
Note: This event does not occur if the sheet has just been recalculated. There is an event called
Calculate which will fire when the worksheet recalculates.
BeforeClose
A useful Workbook related event is BeforeClose. These events can be used to perform
"housekeeping" tasks before a file is saved or closed.
After the new object has been declared with events, it appears in the Object drop-down list box in
the class module, and you can write event procedures for the new object. (When you select the
new object in the Object box, the valid events for that object are listed in the Procedure drop-down
list box.)
Before the procedures will run, however, you must connect the declared object in the class module
with the Application object. You can do this with the following code from any module.
Sub InitializeApp()
Set X.App = Application
End Sub
After you run the InitializeApp procedure, the App object in the class module points to the
Microsoft Excel Application object, and the event procedures in the class module will run when the
events occur.
Note: To find out more information on all events, please consult the Help file for further information.
cel As Boolean)