Access Cookbook, 2nd Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Access Cookbook, 2nd Edition [Electronic resources] - نسخه متنی

Ken Getz; Paul Litwin; Andy Baron

نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
افزودن یادداشت
افزودن یادداشت جدید












Recipe 16.7 Create a Custom Smart Tag DLL




16.7.1 Problem




Users of my application
prefer to use datasheet view for browsing data. I'd
like to provide a smart tag that will enable them to open forms and
reports. How can I create a custom smart tag that will allow users to
open a form that shows all orders for a customer as well as open a
report that shows total sales for a customer?



16.7.2 Solution




If you want to provide conditional processing for
smart tag actions then you must
create a smart tag DLL, using Visual Basic 6.0 or Visual Basic .NET.
In this solution, you'll see how you can use
Visual Basic 6.0 to accomplish this.




If you prefer, you can use Visual Basic .NET to create the smart tag
DLL. In Chapter 17 you'll learn
how to create .NET programs that can be called by Access. For smart
tags, there is no particular advantage to using Visual Basic .NET and
Visual Basic 6.0 will be more familiar to Access programmers who have
worked with VBA, so we have chosen to use Visual Basic 6.0 for this
example.




16.7.2.1 Setting up the DLL project


Follow these steps to create the DLL project using Visual Basic 6.0:



  1. Launch Visual Basic 6.0 and create a new DLL project. The sample
    application is named AccessSmartTag, and it includes one class,
    stActions. The stActions class provides the Actions interface that
    defines the smart tag actions you want to take.



  2. Add the references shown in Figure 16-10. The
    reference to the Microsoft Smart Tags 2.0 Type Library is required.
    This example also has a reference to the Microsoft Access 11.0 Object
    Library so that you can work with Access objects from your smart tag
    code and the Microsoft DAO 3.6 Object Library so that you can work
    with data objects.




Figure 16-10. Setting references to the Microsoft Smart Tags 2.0 Type Library, the Access 11.0 Object Library, and the Microsoft DAO 3.6 Object Library




  1. Place the following statements in the Declarations of the stActions
    class. You do not need a Recognizer interface for a smart tag
    that is designed to work exclusively with Access:


    Option Explicit
    Implements ISmartTagAction
    Implements ISmartTagAction2

  2. The next step is to implement the smart tag action interface by
    creating properties and methods that describe the smart tag action
    DLL. Most of these properties are fairly straightforward and just
    return a requested string. The ISmartTagAction_ProgId( ) is the
    language-independent unique identifier that corresponds to the ProgID
    of the DLL class. In this example, the name of the project is
    AccessSmartTag, and the class name is stActions:


    Private Property Get ISmartTagAction_ProgId( ) As String


    ISmartTagAction_ProgId = "AccessSmartTag.stActions "
    End Property


  3. The ISmartTagAction_Name property is a short phrase that describes
    the DLL:


    Private Property Get ISmartTagAction_Name(ByVal lcid As Long) As String


    ISmartTagAction_Name = "Demo Smart Tag Actions "
    End Property


  4. The ISmartTagAction_Desc property is a longer description of the DLL:


    Private Property Get ISmartTagAction_Desc(ByVal lcid As Long) As String
    ISmartTagAction_Desc = _
    "


    This is a Sample SmartTag used to open Forms and Reports. "
    End Property


  5. The ISmartTagAction_SmartTagCount property reflects the number of
    smart tag types. This example contains one smart tag, so the count is
    1:


    Private Property Get ISmartTagAction_SmartTagCount( ) As Long


    ISmartTagAction_SmartTagCount = 1
    End Property


  6. Each smart tag type is defined by a namespace to keep it unique,
    which is defined in the ISmartTagAction_SmartTagName property.
    SmartTag type names are always in the format of namespaceURI#tagname.
    In this example, the (ismarttag = 1) condition isn't
    strictly necessary since there is only one smart tag type defined,
    but this shows a pattern you could use for handling multiple types:


    Private Property Get ISmartTagAction_SmartTagName(ByVal ismarttag As Long) As String
    If (ismarttag = 1) Then


    ISmartTagAction_SmartTagName = _
    "


    schemas-microsoft-com/smarttag/northwind#openform "
    End If
    End Property


  7. The ISmartTagAction_SmartTagCaption property allows you to specify
    the caption that will be used:


    Private Property Get ISmartTagAction_SmartTagCaption( _
    ByVal ismarttag As Long, ByVal lcid As Long) As String


    ISmartTagAction_SmartTagCaption = "Access Smart Tag Demo "
    End Property


  8. The ISmartTagAction_VerbCount is where you specify the number of
    verbs in the smart tag. In this example, there are two actions that
    the smart tag can take: opening a form or opening a report:


    Private Property Get ISmartTagAction_VerbCount(ByVal bstrName As String) As Long
    If (bstrName = "schemas-microsoft-com/smarttag/northwind#openform") Then


    ISmartTagAction_VerbCount = 2
    End If
    End Property


  9. Smart tag action clients will first ask action DLLs for a unique ID
    integer for each of the verbs it wants to support, passing in the
    name and ordinal number for each one. Generating the unique ID is
    totally up to the action DLL, which gives the action DLL more
    flexibility. For example, a smart tag action DLL can specify the same
    VerbID value for the same action across smart tag types, or it can
    use the same VerbID for similar variants of an action. In this
    example, the ISmartTagAction_VerbID property returns iVerb (the same
    ordinal number passed in) back to the action client as the unique ID:


    Private Property Get ISmartTagAction_VerbID( _
    ByVal bstrName As String, ByVal iVerb As Long) As Long


    ISmartTagAction_VerbID = iVerb
    End Property


  10. The ISmartTagAction_VerbNameFromID property is used internally to
    represent the verb ID:


    Private Property Get ISmartTagAction_VerbNameFromID(ByVal idVerb As Long) _
    As String
    Select Case idVerb
    Case 1
    ISmartTagAction_VerbNameFromID = "openCustomers"
    Case 2
    ISmartTagAction_VerbNameFromID = "openReport"
    Case Else
    ISmartTagAction_VerbNameFromID = "
    End Select
    End Property

  11. The code in the ISmartTagAction2_VerbCaptionFromID2 property checks
    the VerbID and then uses the "///"
    syntax to get cascading menus in the smart tag. Figure 16-11 shows the results when the smart tag is
    accessed in the client application:


    Private Property Get ISmartTagAction2_VerbCaptionFromID2( _
    ByVal VerbID As Long, ByVal ApplicationName As String, _
    ByVal LocaleID As Long, ByVal Properties As SmartTagLib.ISmartTagProperties, _
    ByVal Text As String, ByVal Xml As String, ByVal Target As Object) As String
    If (VerbID = 1) Then
    ISmartTagAction2_VerbCaptionFromID2 = _
    "Smart Tag Actions///Open Customer Form"
    ElseIf (VerbID = 2) Then
    ISmartTagAction2_VerbCaptionFromID2 = _
    "Smart Tag Actions///Open Customer Report"
    End If
    End Property


Figure 16-11. Displaying a fly-out smart tag




  1. The ISmartTagAction2_InvokeVerb2 method provides code to perform the
    actions that the smart tag takes. The first section of the code sets
    a variable to point to the Target, which is the Access control object
    passed in. If the smart tag is defined on a Table object instead of a
    form control, then Access creates a control under the covers that
    gets passed to the smart tag DLL:


    Private Sub ISmartTagAction2_InvokeVerb2( _
    ByVal VerbID As Long, ByVal ApplicationName As String, _
    ByVal Target As Object, ByVal Properties As SmartTagLib.ISmartTagProperties, _
    ByVal Text As String, ByVal Xml As String, ByVal LocaleID As Long)
    On Error GoTo HandleErr:
    Dim cb As Access.Control
    Set cb = Target

  2. The next block of code validates that the control source is
    CustomerID. If not, a MsgBox statement provides feedback to the user
    that the smart tag only works when attached to the CustomerID. If the
    smart tag is attached to CustomerID, the code gets a reference to the
    Access.Application object from the Target's
    Application property:


        If cb.ControlSource <> "CustomerID" Then
    MsgBox "This action only works if you run it on the Customer ID field.", _
    vbOKOnly, "Smart Tag Error"
    GoTo ExitHere
    Else
    Dim app As Access.Application
    Set app = cb.Application
    End If

  3. The code then branches based on VerbID. If the VerbID is 1, then the
    code sets a reference to the Application object's
    CurrentDb property to gain access to DAO objects. This allows the
    code to execute a query to obtain the total number of orders for a
    given CustomerID. This is then retrieved into a DAO Recordset, and
    passed to the Customers form as an OpenArgs argument:


        If VerbID = 1 Then
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Set db = app.CurrentDb
    Dim strQry As String
    Dim strOrders As String
    strQry = "SELECT Count(*) AS NumOrders FROM Orders WHERE CustomerID='" _
    & cb.Value & "';"
    Set rs = db.OpenRecordset(strQry)
    If Not rs.EOF Then
    strOrders = "Total number of orders: " & rs!NumOrders
    Else
    strOrders = "No orders for this customer"
    End If
    rs.Close
    app.DoCmd.OpenForm "Customers", _
    WhereCondition:="[CustomerID] = '" & cb.Value & "'", _
    OpenArgs:=strOrders

  4. If the second action is chosen, then the code opens rptCustomers
    report, passing the CustomerID as the WhereCondition argument
    (without this WhereCondition, the report would open displaying all
    the customers):


        ElseIf VerbID = 2 Then
    app.DoCmd.OpenReport "rptCustomers", _
    View:=acViewPreview, _
    WhereCondition:="[CustomerID] = '" & cb.Value & "'"
    End If

  5. The error handling code is mainly useful for debugging. It displays
    any error information in a MsgBox statement:


    ExitHere:
    Exit Sub
    HandleErr:
    MsgBox Err.Number & " " & Err.Description, _
    vbCritical, "Error in AccessSmartTag.ISmartTagAction2_InvokeVerb2"
    Resume ExitHere
    End Sub


16.7.2.2 Compiling and registering the DLL project


Once you've written the code, build the
DLL project by choosing File
Make AccessSmartTag DLL from the menu. This will create
the correct registry entries. Launch regedit from the Windows Start
Run menu. To obtain the CLSID for the action handler,
navigate to the following node in the Registry:


HKEY_CLASSES_ROOT\AccessSmartTag.stActions\Clsid


Double-click the Clsid node to obtain the value, as shown in Figure 16-12. Copy it to the clipboard and close the
regedit window without saving.



Figure 16-12. Obtaining the Clsid from the AccessSmartTag.stActions



You can then edit the registry directly or create a reg file to
update the registry entries. Use Notepad to create a new file and
name it Reg_AccessSmartTag.reg. The file should contain the following
text. However, you will need to replace the value shown in the curly
braces with the value that you copied to the Clipboard from the
Registry in the previous step:


Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Smart Tag\Actions{9F7503BB-4BBA-
4A4A-B1A5-A0DF0A0187F5}]


In case you ever need to unregister the smart
tag, create a second file named Unreg_AccessSmartTag.reg. The file
should contain the following text. Again, replace the value shown
here in the curly braces with the value copied to the Clipboard:


Windows Registry Editor Version 5.00
[-HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Smart Tag\Actions{9F7503BB-4BBA-
4A4A-B1A5-A0DF0A0187F5}]


Save both files and double-click Reg_AccessSmartTag.reg. This will
create the entries in the registry so that Access can recognize the
smart tag actions.


Open the


16-07.MDB sample database and open the
Customers form in design view. View the code in the
form's Open event, which displays anything passed in
the OpenArgs event in the form's Caption property:


Private Sub Form_Open(Cancel As Integer)
' Display any OpenArgs in the Caption
Dim str As String
str = Me.OpenArgs & "
If Len(str) > 0 Then
Me.Caption = str
End If
End Sub


Close the form and open the Customers table in design view. Assign
the smart tag to the CustomerID field, as shown in Figure 16-13.



Figure 16-13. Assigning the smart tag to the CustomerID field in the Customers table



Save the table and view it in datasheet view. When you choose the
first smart tag action, the Customers form will open with the total
number of orders for the selected customer displayed in the
form's Caption. If you choose the second smart tag
action, then the rptCustomers report will open displaying sales data
for the selected customer.



16.7.3 Discussion




You can write a smart tag DLL in any language that supports writing
COM add-ins. You can also write a smart tag DLL in managed (.NET)
code.


There are two interfaces involved in implementing smart tag actions:
the ISmartTagAction interface and the ISmartTagAction2 interface.
These interfaces provide the client application with the information
needed to support smart tag actions. The ISmartTagAction interface is
compatible with Office XP, and the ISmartTagAction2 interface is
specific to Office 2003, and allows you to tap into new
functionality.




You do not need to implement the ISmartTagRecognizer and
ISmartTagRecognizer2 interfaces in a smart tag DLL targeted
specifically for Access because Access does not use recognizers.



The role of an ISmartTagAction interface is to provide actions for
individual smart tag types. Each smart tag type is defined by a
namespace URI plus its tag name to keep it unique. A
"#" character is appended to the
namespace URI and is used to separate the namespace URI from its tag
name, as shown in this example, where
"schemas-microsoft-com/smarttag/northwind"
is the namespace URI and "openform"
is the tag name. The combination results in the fully qualified name
of the smart tag type. The URI portion of the property name ensures
that it is globally unique and unambiguous, so that two tags with the
same tag name (openform) can be differentiated:


Private Property Get ISmartTagAction_SmartTagName( _
ByVal ismarttag As Long) As String
ISmartTagAction_SmartTagName = _
"


schemas-microsoft-com/smarttag/northwind#openform "
End Property



16.7.3.1 Working with the Access object model


The most interesting part of the sample smart tag DLL is that it
shows you how you can work with the Access object model as well as
DAO. The code in the
ISmartTagAction2_InvokeVerb2 method has an input parameter, Target As
Object, which Access uses to pass in the control that has the smart
tag attached. The code then creates an Access.Control variable that
references the Target:


Dim cb As Access.Control
Set cb = Target


Once you have the
Access Control object, you can then set a
variable to point to the Access Application object, giving you full
access to any part of your application:


Dim app As Access.Application
Set app = cb.Application


From there, you can work with the data in your application by
creating a DAO Database object using the Application
object's CurrentDb property:


Dim db As DAO.Database
Set db = app.CurrentDb


The code goes on to open a Recordset based on a query that counts the
total number of orders for the selected customer, writing it to a
String variable. It then opens the form to display the selected
customer and passes that count value in the OpenArgs argument of the
Application object's DoCmd.OpenForm method:


app.DoCmd.OpenForm "Customers", _
WhereCondition:="[CustomerID] = '" & cb.Value & "'", _


OpenArgs:=strOrders



When the Customers form opens, the code in the Open event evaluates
whether any data has been passed in the OpenArgs argument, and then
displays that information in the form's Caption
property. If the form is opened normally without any OpenArgs data
being passed to it, then the default caption is displayed:


Private Sub Form_Open(Cancel As Integer)
Dim str As String
str = Me.OpenArgs & "
If Len(str) > 0 Then
Me.Caption = str
End If
End Sub


The code for opening a report uses similar techniques. Creating a
smart tag DLL allows you full access to the entire Access object
model, and allows you to create conditional logic for your smart tag.
Smart tags can be a good way to provide extra functionality for users
who prefer working in datasheet view.



16.7.4 See Also




See the Preface for more information on working with DAO to access
data.



/ 232