Late binding wdGoToBookmark

2020-04-20 06:07发布

I have to use late binding. How do i replace the following?

Sub CopyCell(wd As Object, stringcell As String, BookMarkName As String)

       'find Word bookmark
        wd.Selection.GoTo What:=wdGoToBookmark, Name:=BookMarkName

        wd.Selection.TypeText stringcell 
 End Sub

Thx for the much needed help

3条回答
【Aperson】
2楼-- · 2020-04-20 06:18

In Word go to the VB editor and press F2 to bring up the Object Browser - search for wdGoToBookmark to find its numeric value. Use that value in your code or define a Constant as suggested by Mat's mug.

enter image description here

查看更多
仙女界的扛把子
3楼-- · 2020-04-20 06:22

I would d keep it where it is, but declare it as a constant at module level, possibly in its own WordConstants module:

Public Const wdGoToBookmark As Long = -1

Or better, recreate the enum types:

Public Enum WdGoToItem
    wdGoToBookmark = -1
    wdGoToComment = 6
    '...
End Enum

You can find the enum definitions on MSDN

That way this code remains legal:

wd.Selection.GoTo What:=wdGoToBookmark, Name:=BookMarkName

It just doesn't resolve to a constant that's declared in a referenced library anymore.


Alternatively you could hard-code a magic -1 value on-the-spot, but then it becomes much harder to know what it stands for, so putting it in a comment isn't a bad idea:

wd.Selection.GoTo What:=-1, Name:=BookMarkName ' -1: wdGoToBookmark
查看更多
干净又极端
4楼-- · 2020-04-20 06:24

FWIW, I would not simply just create constants and remove early-binding. After all, we early-bound to leverage the ease of development and compile-time validations of our code.

I strongly suggest that you write code so that it can be switched with a flip of switch. For OP's specific code, we can achieve this:

Sub CopyCell(wd As Object, stringcell As String, BookMarkName As String)

#If LateBind Then
  Const wdGoToBookmark As Long = -1
#Else
  Debug.Assert wdGoToBookmark = -1
#End If
       'find Word bookmark
        wd.Selection.GoTo What:=wdGoToBookmark, Name:=BookMarkName

        wd.Selection.TypeText stringcell 
 End Sub

The LateBind const can be either be defined on a per-module in its declaration section as: #Const LateBind = 1

Or it can be defined for whole project by going to Options -> <project name> Properties and putting it in Conditional Compilation Arguments.

This approach can be expanded into other. For example, to create Word.Application, we can do something similar to this:

#If LateBind Then
  Dim app As Object
#Else 
  Dim app As Word.Application
#End If

Set app = CreateObject("Word.Application")

And for functions that needs to take or return objects can have two heads:

#If LateBind Then
Sub CopyCell(wd As Object, stringcell As String, BookMarkName As String)
#Else
Sub CopyCell(wd As Word.Document, stringcell As String, BookMarkName As String)
#End If
  '<rest of procedure body>
End Sub

Why write more code? So that you can simply add/remove the reference to library, change the LateBind constant to the other value, then compile. You now can easily switch between two modes and more importantly you make it very easy for your code to be validated at the compile-time and can be reasonably reassured that it will work equally in late-bound mode. That's not necessarily always true but that's still better than simply dumping any traces of early-bound code, and hoping for the best. Runtime errors are menaces to the developers and should be avoided as much as possible during the development.

查看更多
登录 后发表回答