从VB exe中释放Autocad?没有运气...
大家好,虽然我是VB(A)的新手,但我真的很喜欢使用它(大多数时候)!
目前,我正在为客户开发一个Autocad应用程序。出于各种原因(易于使用,反盗版),我最终希望将VBA宏转换为可执行文件。为此,我向客户邮寄了一个小型测试程序,使用VB6编译,它基本上包括以下内容:
Public AcadObj As AcadApplication
Set AcadObj = CreateObject("AutoCAD.Application")
AcadObj.Visible = True
它在我的系统上工作正常。但是,在邮寄给客户后,他报告了以下错误消息:
运行时错误“429”ActiveX组件无法创建对象
,所以我给他邮寄了下一个版本的测试程序,其代码派生自Joe Sutphin的Autocad 2006 VBA书籍:
Public AcadObj As AcadApplication
Set AcadObj = CreateObject(Class:="AutoCAD.Application")
AcadObj.Visible = True
现在客户报告了另一条错误消息:
运行时错误“13”类型不匹配
他还提到他的系统上有多个版本的Autocad:R14,2006LT和2006完整版。不要问为什么。因此,我在这里和其他地方寻找解决方案,并发现了以下内容:
Public AcadObj As AcadApplication
Set AcadObj = CreateObject("AutoCAD.Application.16.2")
AcadObj.Visible = True
添加的“16.2”应该确保启动Autocad 2006完整版。然而,这次尝试使我们回到了正方形1:
运行时错误“429”ActiveX组件无法创建对象
同时,为了验证代码是否应该在其他系统上工作,我用XP Home和Autocad 2006完整版的全新安装组装了我的一台古老的PC(PII 300MHz,128MB内存)。我的测试程序的所有三个版本都完美地启动了Autocad!
任何想法为什么我的客户的测试运行不断返回错误,有人吗?
**** Hidden Message ***** 当您在设计时已经绑定了类型库时,尝试后期绑定时,这可能是一个问题。
试试这个:
Function GetAcadObject(Optional ByVal AcadVersion As Variant) As Object
On Error Resume Next
Set GetAcadObject = GetObject(, "AutoCAD.Application" & AcadVersion)
If Err0 Then
Err.Clear
Set GetAcadObject = CreateObject("AutoCAD.Application" & AcadVersion)
If Err0 Then
MsgBox "Could not load or find AutoCAD.", vbExclamation
End
End If
End If
End Function
现在确保在完成代码编写后删除对AutoCAD类型库的所有引用,此外,每当您需要在程序中将AutoCAD实体作为对象包含时,请确保将其引用为“对象”,而不是AcadApplication或AcadLWPolyline或任何Acadxxxxxxx,因为如果所需的类型ibrary与设计时类型库不同,它会导致问题。
您还需要维护对创建(或引用)的 AcadObject 的有效引用,以使程序正常运行。例如:如果将 AC 设置为 AutoCAD 应用程序对象,则需要使用 AC.property 或 AC.method,而不是直接引用方法或属性。
如果您需要特定版本的AutoCAD来使用您的程序,则可以这样称呼它:
Set AC = GetAcadObject(".15")
对于与版本无关的引用
Set AC = GetAcadObject()
感谢您的快速回复,Keith!
您的第一行让我有些困惑(作为新手),但我想它们的意思是我最好不要编译引用与客户使用的Autocad类型库不同的VB代码。
好的,我会记住的。虽然我认为由于应用程序将与Autocad 2006一起构建
和
(根据客户的特殊要求),这些库是相同的。
您在帖子中包含的代码片段与我的测试程序的第一个版本中的代码非常相似,除了我跳过了GetObject位和固有的错误捕获。
事实上,我的未来应用程序将加载Autocad实体。因此,如果类型库问题被证明是问题所在,那么在将VBA宏转换为VB可执行文件时,我将有很多重新编码的工作要做。
事实上,我希望我的问题的原因不那么令人沮丧。如前所述,我发现CreateObject参数中的版本规范是Autocad 2006的“.16.2”。是否Autocad 2006 LT和Autocad 2006完整版本的规范相同,这可能会在我的客户系统上引起冲突?如果是这样,一个简单的解决方案是仅使用GetObject语句,如果这导致错误,则显示一个消息框,敦促用户(独占)启动Autocad 2006完整版本,并暂停进一步执行,直到他这样做。也许是这样的:
Private Sub cmdLookForOpenAutocad2006FullVersion() 'commandbutton
Dim strMsg As String
strMsg = "Please launch Autocad 2006 full version" & vbCr
strMsg = strMsg & "(first close any other Autocad version)"
On Error Resume Next
Set AcadObj = GetObject(, "AutoCAD.Application.16.2")
If Err Then MsgBox (strMsg): Exit Sub 'Acad 2006 full version not open
'if not error, continue with the sub
哈瓦诺,我不使用vb(只有vba),所以我没有你的问题,得到autocad,但我有相同类型的问题得到Excel。一旦您
Dim Excel AsExcel.Application
您将被委托在每台将运行此代码的机器上设置正确版本的Excel。
您可以通过在工具中设置正确的引用来做到这一点->vbaide中的引用(您在其中编码)
这是非常棘手的,但还有另一种方法,后期绑定。
后期绑定不需要任何引用,并且会在计算机上查找默认版本的excel。
但您现在必须将所有内容都调暗为对象,请参阅下文。
Dim Excel As Object
Dim ExcelSheet As Object
Dim ExcelWorkbook As Object
Dim strSaveName As String
Dim i As Intger, j As Intger, k作为整数
在错误恢复下一步
设置Excel=GetObject(,"Excel.Application")
如果错误0然后
设置Excel=CreateObject("Excel.Application")
结束如果
在错误转到0
设置ExcelWorkbook=Excel.Workbooks.Open(strXLpath)
虽然ExcelWorkbook作为对象变暗,但您仍然将其用作工作簿,并且它具有工作簿的属性。
啊,现在我更明白晚绑定的含义了。至少我认为我知道。谢谢布里科!
尽管如此,我认为我将坚持这个项目的早期绑定:客户坚持Autocad 2006(和单独的2006)的兼容性,我有什么可争辩的呢?
我的客户的系统上的“竞争”Autocad版本之一是Autocad 2006 LT。无论是哪种类型库,尝试从VB访问Lite版本都会导致错误。
因此,现在我将集中讨论如何在多Acad版本环境中从VB成功启动或访问Autocad 2006完整版。任何关于这方面的建议都将受到高度赞赏。 出于以下原因使用后期绑定...您的客户可能会在几年内升级到较新版本的acad。
此代码在运行之前会失败,因为它使用对 acad 对象的引用,并且解释器将停止 - 扫描您的代码。
选项 Explicit
Public AcadObj As Object
'----------
Private Sub StartAutocad_Click()
'查找 Autocad 2006 (完整版)
On Error Resume Next
Set AcadObj = GetObject(, “AutoCAD.Application.16.2”)
如果 Err0 则
Err.Clear
Set AcadObj = CreateObject(“AutoCAD.Application.16.2”)
如果 Err0 则 ErrorMessage: Exit Sub 'Get and Create failed
End If
'Get or Create Acad 2006 (完整版?) 成功
Err.Clear: 在错误GoTo 0
AcadObj.Visible = True
End Sub
'----------
Private Sub DrawTextstring_Click()
On Error Resume Next
Dim textObj As Object '这是对acad对象的直接引用以及
Dim text As String
Dim insPt(0 To 2) As Double
Dim Height As Double
' 定义文本对象
文本= “.测试成功。
insPt(0) = 2: insPt(1) = 2: insPt(2) = 0
高度 = 0.5
' 在模型空间中创建文本对象
Set textObj = AcadObj.ActiveDocument.ModelSpace.AddText(text, insPt, height)
AcadObj.ZoomExtents
If Err0 Then ErrorMessage 'Autocad 2006 LT 可能破坏了乐趣...
End Sub
'----------
Private Sub Exit_Click()
On Error Resume Next 'just in case button 在 Acad 未加载
AcadObj 的情况下被单击。Quit
Unload Me
End Sub
'----------
Private Sub ErrorMessage()
Err.Clear: On Error GoTo 0
Dim strMsg As String
strMsg = “找不到或启动 Autocad 2006 完整版。” & vbCr
strMsg = strMsg & “请关闭所有其他版本和” & vbCr
strMsg = strMsg & “自己启动 Autocad 2006 完整版。
MsgBox (strMsg)
End Sub
使用后期绑定的关键是 earlly bind,同时发展意识到将 acad 常量更改为它们的值,并将所有分配给 acad 对象的操作更改为“as Object”
并删除引用。
嗨,Berend,谢谢你的评论,最重要的是,你把我的代码改写成一个后期绑定版本。
如果其他方法都失败,我将稍后尝试。顺便说一句,你忘了删除Acadverson参数,这会破坏getobject和createobject部分。
但是请原谅我在这个问题上略有不同的看法:作为个体经营者,我未来的收入可能很大一部分甚至完全由维护费组成...
明白我的意思吗?:kewl:
Groet!
顺便说一句,您忘了删除Acadverson属性,这将使GetObject和CreateObject受挫,因为这样版本依赖性就会溜回来。
是的,我理解你做生意的方式,但我不认为这是继续欺骗你的客户的最好方式。
(除了白天的工作,还有一份小生意) 我有预感你会有那样的反应。抱歉,如果我让你不高兴了。
我曾经拥有你的道德。那是我拿到你每月薪水的时候。
如果我告诉您,我允许客户在这一点上“欺骗”我,只是希望有一天能够报复,这会有帮助吗?相信我,我仍然设法保持正直和狭窄。我最不希望或应得的就是被人看不起。伦理问题谈够了,让我们回到主题上来。
是的,请。
页:
[1]
2