Late binding now failing

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mike MacSween

    Late binding now failing

    Had some trouble with Word automation. Sorted it, in the process thought I
    would try late binding. Some people reccomend it. So this:
    *************** *************** *************** ************
    Public Sub MailMerge(strQu ery As String, strTemplate As String)
    snip
    Dim doc As Word.Document
    Dim wrdApp As Word.Applicatio n
    snip

    Set wrdApp = New Word.Applicatio n
    Set doc = wrdApp.Document s.Add(strPath & strTemplate)

    With doc.MailMerge
    ..Destination = wdSendToNewDocu ment
    ..SuppressBlank Lines = True
    With .DataSource
    ..FirstRecord = wdDefaultFirstR ecord
    ..LastRecord = wdDefaultLastRe cord
    End With
    If .State = wdMainAndDataSo urce Then .Execute
    End With
    wrdApp.Visible = True
    snip
    End Sub
    *************** *************** *************** ************
    works, with a reference to the Word olb

    If i change it to:
    *************** *************** *************** ************
    Public Sub MailMerge(strQu ery As String, strTemplate As String)
    snip
    Dim doc As object
    Dim wrdApp as object
    snip

    Set wrdApp = CreateObject("W ord.Application ")
    Set doc = wrdApp.Document s.Add(strPath & strTemplate)

    With doc.MailMerge
    ..Destination = wdSendToNewDocu ment
    ..SuppressBlank Lines = True
    With .DataSource
    ..FirstRecord = wdDefaultFirstR ecord
    ..LastRecord = wdDefaultLastRe cord
    End With
    If .State = wdMainAndDataSo urce Then .Execute
    End With
    wrdApp.Visible = True
    snip
    End Sub
    *************** *************** *************** ************
    it halts on
    ..Destination = wdSendToNewDocu ment
    with wdSendToNewDocu ment highlighted and 'unknown variable'

    Any ideas?

    TIA, Mike MacSween


  • MacDermott

    #2
    Re: Late binding now failing

    wdSendToNewDocu ment
    is defined in the Word olb.
    If you don't have a reference to that library, you can't resolve this name.

    If you do have a reference to the library, you can find the numeric value of
    wdSendToNewDocu ment
    and put that into your code. I see there are a couple more of these terms
    from the Word olb you'll have to do the same with if you want to remove the
    reference to the olb.

    HTH
    - Turtle

    "Mike MacSween" <mike.macsween. nospam@btintern et.com> wrote in message
    news:3f7c9e6f$0 $215$bed64819@p ubnews.gradwell .net...[color=blue]
    > Had some trouble with Word automation. Sorted it, in the process thought I
    > would try late binding. Some people reccomend it. So this:
    > *************** *************** *************** ************
    > Public Sub MailMerge(strQu ery As String, strTemplate As String)
    > snip
    > Dim doc As Word.Document
    > Dim wrdApp As Word.Applicatio n
    > snip
    >
    > Set wrdApp = New Word.Applicatio n
    > Set doc = wrdApp.Document s.Add(strPath & strTemplate)
    >
    > With doc.MailMerge
    > .Destination = wdSendToNewDocu ment
    > .SuppressBlankL ines = True
    > With .DataSource
    > .FirstRecord = wdDefaultFirstR ecord
    > .LastRecord = wdDefaultLastRe cord
    > End With
    > If .State = wdMainAndDataSo urce Then .Execute
    > End With
    > wrdApp.Visible = True
    > snip
    > End Sub
    > *************** *************** *************** ************
    > works, with a reference to the Word olb
    >
    > If i change it to:
    > *************** *************** *************** ************
    > Public Sub MailMerge(strQu ery As String, strTemplate As String)
    > snip
    > Dim doc As object
    > Dim wrdApp as object
    > snip
    >
    > Set wrdApp = CreateObject("W ord.Application ")
    > Set doc = wrdApp.Document s.Add(strPath & strTemplate)
    >
    > With doc.MailMerge
    > .Destination = wdSendToNewDocu ment
    > .SuppressBlankL ines = True
    > With .DataSource
    > .FirstRecord = wdDefaultFirstR ecord
    > .LastRecord = wdDefaultLastRe cord
    > End With
    > If .State = wdMainAndDataSo urce Then .Execute
    > End With
    > wrdApp.Visible = True
    > snip
    > End Sub
    > *************** *************** *************** ************
    > it halts on
    > .Destination = wdSendToNewDocu ment
    > with wdSendToNewDocu ment highlighted and 'unknown variable'
    >
    > Any ideas?
    >
    > TIA, Mike MacSween
    >
    >[/color]


    Comment

    • Pieter Linden

      #3
      Re: Late binding now failing

      Mike,

      wdSendToNewDocu ment is a named constant or something like that. What
      if you cheat and do something like

      ?wdSendToNewDoc ument

      in the immediate window, get the number/value associated with this
      variable and use that number instead? Does it work?

      just a haphazard guess, so don't spend any more than 30 seconds
      playing with it...

      Comment

      • Mike MacSween

        #4
        Re: Late binding now failing

        "MacDermott " <macdermott@nos pam.com> wrote in message
        news:WF2fb.1286 6$f11.4061@news read1.news.atl. earthlink.net.. .[color=blue]
        > wdSendToNewDocu ment
        > is defined in the Word olb.
        > If you don't have a reference to that library, you can't resolve this[/color]
        name.[color=blue]
        >
        > If you do have a reference to the library, you can find the numeric value[/color]
        of[color=blue]
        > wdSendToNewDocu ment
        > and put that into your code. I see there are a couple more of these terms
        > from the Word olb you'll have to do the same with if you want to remove[/color]
        the[color=blue]
        > reference to the olb.[/color]

        Thanks Turtle, that worked perfectly. Though I don' really understand. If
        using CreateObject() to use automation gives me access to the Word methods
        and properties, why not the constants?

        Not sure which way to swing on this now. There seems to be a conflict. All
        the literature says 'use early binding unless there's a very good reason not
        to' whereas a lot of people say use late binding. Some advise using early in
        development (to get the intellisense etc.) then change to late for
        distribution. But if I'm going to have to find constant values myself that
        loses some advantage. And I read to always use late if using MDEs.

        Whaddya think?

        Cheers, Mike


        Comment

        • Mike MacSween

          #5
          Re: Late binding now failing

          "Pieter Linden" <pietlinden@hot mail.com> wrote in message
          news:bf31e41b.0 310021755.18553 95b@posting.goo gle.com...[color=blue]
          > Mike,
          >
          > wdSendToNewDocu ment is a named constant or something like that. What
          > if you cheat and do something like
          >
          > ?wdSendToNewDoc ument[/color]

          Thanks Pieter, that did it.

          Cheers, Mike


          Comment

          • Tony Toews

            #6
            Re: Late binding now failing

            "Mike MacSween" <mike.macsween. nospam@btintern et.com> wrote:

            No idea as to why constants can't be used. That said someone stated that he didn't
            have any problem leaving the constants in the Access app when he changed back to
            early binding for some more programming.

            So you could Const them at the top of a module anyhow.
            [color=blue]
            >Not sure which way to swing on this now. There seems to be a conflict. All
            >the literature says 'use early binding unless there's a very good reason not
            >to' whereas a lot of people say use late binding. Some advise using early in
            >development (to get the intellisense etc.) then change to late for
            >distribution . But if I'm going to have to find constant values myself that
            >loses some advantage. And I read to always use late if using MDEs.[/color]

            To me the issue is "Could there be a different version of xxx to which you have a
            reference?" If Outlook, Word, Excel, ... then that's a very good possibility even
            if in one organization. For example, and this happened to me, the IT guy upgraded
            his version of Outlook just to play with things. And it promptly broke the app which
            automatically sent out emails via Outlook for him.

            Tony
            --
            Tony Toews, Microsoft Access MVP
            Please respond only in the newsgroups so that others can
            read the entire thread of messages.
            Microsoft Access Links, Hints, Tips & Accounting Systems at

            Comment

            • Lyle Fairfield

              #7
              Re: Late binding now failing

              "Mike MacSween" <mike.macsween. nospam@btintern et.com> wrote in
              news:3f7cf8ed$0 $217$bed64819@p ubnews.gradwell .net:
              [color=blue]
              > "MacDermott " <macdermott@nos pam.com> wrote in message
              > news:WF2fb.1286 6$f11.4061@news read1.news.atl. earthlink.net.. .[color=green]
              >> wdSendToNewDocu ment
              >> is defined in the Word olb.
              >> If you don't have a reference to that library, you can't resolve this[/color]
              > name.[color=green]
              >>
              >> If you do have a reference to the library, you can find the numeric
              >> value[/color]
              > of[color=green]
              >> wdSendToNewDocu ment
              >> and put that into your code. I see there are a couple more of these
              >> terms from the Word olb you'll have to do the same with if you want to
              >> remove[/color]
              > the[color=green]
              >> reference to the olb.[/color]
              >
              > Thanks Turtle, that worked perfectly. Though I don' really understand.
              > If using CreateObject() to use automation gives me access to the Word
              > methods and properties, why not the constants?
              >
              > Not sure which way to swing on this now. There seems to be a conflict.
              > All the literature says 'use early binding unless there's a very good
              > reason not to' whereas a lot of people say use late binding. Some advise
              > using early in development (to get the intellisense etc.) then change to
              > late for distribution. But if I'm going to have to find constant values
              > myself that loses some advantage. And I read to always use late if using
              > MDEs.
              >
              > Whaddya think?
              >
              > Cheers, Mike[/color]

              The constants are contained in the type library, not in the object. And
              late binding does not require a type library, it simply binds the object's
              name to its Dispatch ID. It does this at run-time, so if there's a problem,
              that's when it will arise. Many developers want to know about problems at
              compile time and so, even if the claimed speed advantage of early binding
              seems to be exaggerated, they prefer early.

              A problem with MDEs is that references cannot be changed. Perhaps, that is
              why late binding is recommended for MDEs. IMO MDEs are sound devices for
              those who write entirely original and supremely valuable code. They are
              also helpful for the paranoid and those whose experience is so limited that
              they think that they have created something wonderful and unique. I am
              paranoid only about the Fascist Right, Religious Fundamentalists , the New
              York Yankees, the USA Olympic Committee and other such nefarious groups. So
              I don't use MDEs. And I know that I am neither wonderful nor unique.
              Consider my evil twin, Kyle ...

              --
              Lyle
              (for e-mail refer to http://ffdba.com/contacts.htm)

              Comment

              • Mike MacSween

                #8
                Re: Late binding now failing

                "Lyle Fairfield" <MissingAddress @Invalid.Com> wrote in message
                news:Xns940914B AB3AEAFFDBA@130 .133.1.4...
                [color=blue]
                > The constants are contained in the type library, not in the object. And
                > late binding does not require a type library, it simply binds the object's
                > name to its Dispatch ID.[/color]

                Got it (I think):

                object.property = 1

                but if you want you can refer to 1 by saying "wdNewDoc", but only if you use
                our library, where we've enumerated the constants. Or something like that.
                [color=blue]
                > It does this at run-time, so if there's a problem,
                > that's when it will arise. Many developers want to know about problems at
                > compile time and so, even if the claimed speed advantage of early binding
                > seems to be exaggerated, they prefer early.[/color]

                Yes, I can see that. Many developers would include me. But of course I'd
                also like to know that something that runs just fine here, won't fall to
                bits when it goes onto a client's machine, just because they have build
                version 9.34.34.4334 of MS OfficeProduct, which is one build later than
                mine. Does location make a difference? For instance I always install Office
                into C:\Office XXX, with having so many different versions, whereas clients
                will usually/often have the default of c:\program files\etc.

                I can see the advantages of develop early, deploy late. (Does that sound
                like some sort of new 'developement paradigm')
                [color=blue]
                > A problem with MDEs is that references cannot be changed. Perhaps, that is
                > why late binding is recommended for MDEs.[/color]

                I just like the idea of stopping people tinkering! That's my job.
                [color=blue]
                > IMO MDEs are sound devices for
                > those who write entirely original and supremely valuable code.[/color]

                See, you've been looking at my code again. If compiled to an MDE!
                [color=blue]
                > They are
                > also helpful for the paranoid and those whose experience is so limited[/color]
                that[color=blue]
                > they think that they have created something wonderful and unique. I am
                > paranoid only about the Fascist Right, Religious Fundamentalists , the New
                > York Yankees, the USA Olympic Committee and other such nefarious groups.[/color]

                Don't know about 3 and 4, they're in the American Colonies, yes? I know what
                you mean about 1 and 2 though.

                Mike


                Comment

                • MacDermott

                  #9
                  Re: Late binding now failing

                  Here's another way of thinking of it:
                  Access doesn't know that you're making wrd into a Word object until
                  CreateObject is executed -
                  long after compile time, when it's trying to resolve constants, and
                  notices it doesn't know what wdSendToNewDocu ment means.
                  (Actually, as one poster comments, it doesn't even recognize the
                  constant after the object has been created, because the definition is in the
                  type library, not the object library.)

                  Personally, in such cases I like the solution of declaring constants at the
                  top of your module.

                  HTH
                  - Turtle

                  "Mike MacSween" <mike.macsween. nospam@btintern et.com> wrote in message
                  news:3f7cf8ed$0 $217$bed64819@p ubnews.gradwell .net...[color=blue]
                  > "MacDermott " <macdermott@nos pam.com> wrote in message
                  > news:WF2fb.1286 6$f11.4061@news read1.news.atl. earthlink.net.. .[color=green]
                  > > wdSendToNewDocu ment
                  > > is defined in the Word olb.
                  > > If you don't have a reference to that library, you can't resolve this[/color]
                  > name.[color=green]
                  > >
                  > > If you do have a reference to the library, you can find the numeric[/color][/color]
                  value[color=blue]
                  > of[color=green]
                  > > wdSendToNewDocu ment
                  > > and put that into your code. I see there are a couple more of these[/color][/color]
                  terms[color=blue][color=green]
                  > > from the Word olb you'll have to do the same with if you want to remove[/color]
                  > the[color=green]
                  > > reference to the olb.[/color]
                  >
                  > Thanks Turtle, that worked perfectly. Though I don' really understand. If
                  > using CreateObject() to use automation gives me access to the Word methods
                  > and properties, why not the constants?
                  >
                  > Not sure which way to swing on this now. There seems to be a conflict. All
                  > the literature says 'use early binding unless there's a very good reason[/color]
                  not[color=blue]
                  > to' whereas a lot of people say use late binding. Some advise using early[/color]
                  in[color=blue]
                  > development (to get the intellisense etc.) then change to late for
                  > distribution. But if I'm going to have to find constant values myself that
                  > loses some advantage. And I read to always use late if using MDEs.
                  >
                  > Whaddya think?
                  >
                  > Cheers, Mike
                  >
                  >[/color]


                  Comment

                  • Mike MacSween

                    #10
                    Re: Late binding now failing

                    "MacDermott " <macdermott@nos pam.com> wrote in message
                    news:2Kdfb.1448 8$3S.11874@news read2.news.atl. earthlink.net.. .[color=blue]
                    > Here's another way of thinking of it:
                    > Access doesn't know that you're making wrd into a Word object until
                    > CreateObject is executed -
                    > long after compile time, when it's trying to resolve constants,[/color]
                    and[color=blue]
                    > notices it doesn't know what wdSendToNewDocu ment means.
                    > (Actually, as one poster comments, it doesn't even recognize the
                    > constant after the object has been created, because the definition is in[/color]
                    the[color=blue]
                    > type library, not the object library.)[/color]

                    Yes, I understand
                    [color=blue]
                    > Personally, in such cases I like the solution of declaring constants at[/color]
                    the[color=blue]
                    > top of your module.[/color]

                    I just worked that out. I guess a strategy would be to start with early
                    binding (nice intellisense), compile (nice type checking), then remove the
                    reference. Then compile and each time it chokes change first the early
                    binding declaration and then each constant as it chokes on them one by one.

                    Thanks for your help.

                    Mike


                    Comment

                    • David W. Fenton

                      #11
                      Re: Late binding now failing

                      MissingAddress@ Invalid.Com (Lyle Fairfield) wrote in
                      <Xns940914BAB3A EAFFDBA@130.133 .1.4>:
                      [color=blue]
                      >The constants are contained in the type library, not in the
                      >object. And late binding does not require a type library, it
                      >simply binds the object's name to its Dispatch ID. It does this at
                      >run-time, so if there's a problem, that's when it will arise. Many
                      >developers want to know about problems at compile time and so,
                      >even if the claimed speed advantage of early binding seems to be
                      >exaggerated, they prefer early.[/color]

                      I code with early binding, deliver with late.
                      [color=blue]
                      >A problem with MDEs is that references cannot be changed. Perhaps,
                      >that is why late binding is recommended for MDEs. IMO MDEs are
                      >sound devices for those who write entirely original and supremely
                      >valuable code. They are also helpful for the paranoid and those
                      >whose experience is so limited that they think that they have
                      >created something wonderful and unique. I am paranoid only about
                      >the Fascist Right, Religious Fundamentalists , the New York
                      >Yankees, the USA Olympic Committee and other such nefarious
                      >groups. So I don't use MDEs. And I know that I am neither
                      >wonderful nor unique. Consider my evil twin, Kyle ...[/color]

                      MDE's have a number of advantages not related to your arrogance
                      argument:

                      1. the code cannot be changed. This means that you don't have to
                      consider whether or not a user has gotten in there and made a
                      change, accidentally or not. I've seen it accidentally when an
                      untrapped error gets the user into debug mode, and they hit the
                      ENTER key or otherwise type some character. This will quite often
                      lead to permanently broken, uncompilable code (assuming the changes
                      are saved). With an MDE, this simply can't ever happen, so it
                      streamlines troubleshooting .

                      2. the code can never decompile, so performance can never degrade
                      because of decompiled code.

                      3. performance can be noticeably better, both because of smaller
                      file size but also because 2) can't happen.

                      Those are all rational reasons for shipping MDEs.

                      That said, I've got no current projects delivered as MDEs.

                      --
                      David W. Fenton http://www.bway.net/~dfenton
                      dfenton at bway dot net http://www.bway.net/~dfassoc

                      Comment

                      • David W. Fenton

                        #12
                        Re: Late binding now failing

                        mike.macsween.n ospam@btinterne t.com (Mike MacSween) wrote in
                        <3f7d24fb$0$210 $bed64819@pubne ws.gradwell.net >:
                        [color=blue]
                        >"Lyle Fairfield" <MissingAddress @Invalid.Com> wrote in message
                        >news:Xns940914 BAB3AEAFFDBA@13 0.133.1.4...
                        >[color=green]
                        >> The constants are contained in the type library, not in the
                        >> object. And late binding does not require a type library, it
                        >> simply binds the object's name to its Dispatch ID.[/color]
                        >
                        >Got it (I think):
                        >
                        >object.propert y = 1
                        >
                        >but if you want you can refer to 1 by saying "wdNewDoc", but only
                        >if you use our library, where we've enumerated the constants. Or
                        >something like that.[/color]

                        In Access terms it would be like this:

                        In mdlWord:

                        Private Const wdNewDoc = 1

                        If you run code from mdlNotWord, it won't know the value of
                        wdNewDoc because the constant is not public.

                        The object reference is your link to the otherwise "private"
                        constants of Word.

                        Keep in mind that even though you create the object, you are still
                        *acting* on that object in Access, not in Word itself, so the
                        constants need to be known to Access itself.

                        --
                        David W. Fenton http://www.bway.net/~dfenton
                        dfenton at bway dot net http://www.bway.net/~dfassoc

                        Comment

                        • David W. Fenton

                          #13
                          Re: Late binding now failing

                          macdermott@nosp am.com (MacDermott) wrote in
                          <2Kdfb.14488$3S .11874@newsread 2.news.atl.eart hlink.net>:
                          [color=blue]
                          >Here's another way of thinking of it:
                          > Access doesn't know that you're making wrd into a Word object
                          > until
                          >CreateObject is executed -
                          > long after compile time, when it's trying to resolve
                          > constants, and
                          >notices it doesn't know what wdSendToNewDocu ment means.
                          > (Actually, as one poster comments, it doesn't even
                          > recognize the
                          >constant after the object has been created, because the definition
                          >is in the type library, not the object library.)
                          >
                          >Personally, in such cases I like the solution of declaring
                          >constants at the top of your module.[/color]

                          When VBA code is compiled, constants are compiled in literally, not
                          as references to the variable name. If you refer to a constant
                          value for an object that hasn't been instantiated, it can't
                          possibly be compiled in literally.

                          --
                          David W. Fenton http://www.bway.net/~dfenton
                          dfenton at bway dot net http://www.bway.net/~dfassoc

                          Comment

                          • David W. Fenton

                            #14
                            Re: Late binding now failing

                            mike.macsween.n ospam@btinterne t.com (Mike MacSween) wrote in
                            <3f7d7d12$0$214 $bed64819@pubne ws.gradwell.net >:
                            [color=blue]
                            >"MacDermott " <macdermott@nos pam.com> wrote in message
                            >news:2Kdfb.144 88$3S.11874@new sread2.news.atl .earthlink.net. ..[color=green]
                            >> Personally, in such cases I like the solution of declaring
                            >> constants at[/color]
                            >the[color=green]
                            >> top of your module.[/color]
                            >
                            >I just worked that out. I guess a strategy would be to start with
                            >early binding (nice intellisense), compile (nice type checking),
                            >then remove the reference. Then compile and each time it chokes
                            >change first the early binding declaration and then each constant
                            >as it chokes on them one by one.[/color]

                            What I've done is copied the constant declarations as comments at
                            the top of the code using them:


                            ' wdDefaultFirstR ecord = 1

                            and then use the literal value in the actual code, but with the
                            named constant as a trailing comment:

                            .FirstRecord = 1 ' wdDefaultFirstR ecord

                            This means I only have to change the definitions of the objects
                            themselves, but still have an audit trail back into the constant
                            names (particularly useful if you're trying to reconcile your
                            late-bound code with other code that's early bound).

                            --
                            David W. Fenton http://www.bway.net/~dfenton
                            dfenton at bway dot net http://www.bway.net/~dfassoc

                            Comment

                            • Mike MacSween

                              #15
                              Re: Late binding now failing

                              "David W. Fenton" <dXXXfenton@bwa y.net.invalid> wrote in message[color=blue]
                              >
                              > In Access terms it would be like this:
                              >
                              > In mdlWord:
                              >
                              > Private Const wdNewDoc = 1
                              >
                              > If you run code from mdlNotWord, it won't know the value of
                              > wdNewDoc because the constant is not public.
                              >
                              > The object reference is your link to the otherwise "private"
                              > constants of Word.
                              >
                              > Keep in mind that even though you create the object, you are still
                              > *acting* on that object in Access, not in Word itself, so the
                              > constants need to be known to Access itself.[/color]

                              Thanks David. I'm declaring thus:

                              Public Sub MailMerge(strQu ery As String, strTemplate As String)
                              Const wdSendToNewDocu ment As Integer = 0
                              more declarations here
                              some code here
                              End sub

                              So they're still local variables, even though the procedure's public, yes?
                              Which is what I want. Though it's highly unlikely that I'm going to be
                              declaring any other variable with the same names as these (except to do
                              exactly the same thing) anyway. Still, I can't see any need for them to be
                              public.

                              Cheers, Mike


                              Comment

                              Working...