我想在VBA 7.0中创建一个无模式弹出对话框.到目前为止,最有希望的路线似乎是CreateDialog
.
首先我尝试CreateDialogW
并收到了Entry point not found for CreateDialogW in DLL
.
打开DLL后,我验证了此功能未列出.上面链接的MSDN参考显示User32作为此函数的DLL并列出函数名称CreateDialogW
和CreateDialogA
(Unicode/ansi),但它们未在我的计算机上的此DLL中列出(Win 7 professional,64bit).
所以,看的是功能列表是在DLL中,我看到的CreateDialogParam
和CreateDialogIndirectParam
函数(每ANSI和Unicode版本).
我一直在尝试遵循MSDN并将C示例转换为VB,但我在某处遗漏了某些东西而且我有点卡住,因为我不知道我做错了什么.代码编译并运行没有错误,但API调用没有任何反应 - 它执行但没有任何反应.
如果有人能给我一些正确方向的指示,我将非常感激.我当前的解决方法很糟糕,我真的很想按下这个项目.
Option Explicit
'Reference conversion of C to VB type declarations here
'http://msdn.microsoft.com/en-us/library/aa261773(v=vs.60).aspx
'Declare function to Win API CreateDialog function
'http://msdn.microsoft.com/en-us/library/ms645434(v=vs.85).aspx
Private Declare PtrSafe Function CreateDialog Lib "User32.dll" Alias "CreateDialogParamW" _
(ByVal lpTemplateName As LongPtr, _
ByRef lpDialogFunc As DIALOGPROC, _
ByVal dwInitParam As Long, _ …
Run Code Online (Sandbox Code Playgroud) 只是一个我似乎无法找到答案的问题.
我是以编程方式创建用户表单,我发现如果我将对象声明为"MSForms.Userform"类型,似乎无法设置高度和宽度,因为这些属性不存在,并且内部高度/ insidewidth是只读属性.
我发现如果我将它声明为通用类型"对象",我可以设置高度和宽度属性并完全按照我的意愿使用它.
因此,在我初始化对象后,我检查了本地窗口,差异似乎是:
所以我的问题是,使用不同的声明语句有什么区别?
谢谢!
编辑:添加了一些示例代码,以便您可以看到oject在声明方式不同时的行为方式.
(我无法正确显示此代码块 - 即使声明为基本语言)
Sub TestUserForm()
'NOTE: You need to add a reference to Microsoft Visual Basic
' for Applications Extensibility 5.3
'Declare variables
Dim oForm As MSForms.UserForm
Dim oForm1 As Object
Dim oComp As VBComponent
Dim oComp1 As VBComponent
'Create new form objects in the VBA project programmatically
Set oComp = Application.VBE.ActiveVBProject.VBComponents.Add(ComponentType:=vbext_ct_MSForm)
Set oComp1 = Application.VBE.ActiveVBProject.VBComponents.Add(ComponentType:=vbext_ct_MSForm)
'Initailize an object of each new form
Set oForm = VBA.UserForms.Add(oComp.Name)
Set oForm1 = …
Run Code Online (Sandbox Code Playgroud) 好的,我可能会离开这里,但我想要做的是使用GetOpenFileName的API调用的宽(Unicode)版本来返回多个文件的列表.
现在,我想这样做的原因是:选择多个文件时,文件名的总字符数限制取决于函数的版本.
•ANSI:32k限制
•Unicode:无限制
从深埋在我的网络中的目录中返回大量文件可能会快速超过ANSI 32k字符限制.
所以,我所做的是采用我的ANSI声明函数,并string
用lngptr
.替换所有声明的变量.然后我需要为这些值赋值,我已经使用该StrPtr()
函数来转换字符串值.
现在,当我尝试调用此函数时,它到达调用Declared函数的部分,它lReturn = GetOpenFileNameU(OpenFile)
实际上并没有做任何事情!没有错误,没有 - 只是走过那条线,没有任何反应.我做错了什么??
这就是我现在所处的位置:
Option Explicit
'***NOTE: _
This class object requires the following references: _
<NONE>
'Declare the windows API function for GetOpenFileNameA
'MSDN Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646927(v=vs.85).aspx
Public Declare PtrSafe Function GetOpenFileNameU Lib "comdlg32.dll" Alias "GetOpenFileNameW" (pOpenfilename As OPENFILENAME) As Long
Public Const OFN_ALLOWMULTISELECT As Long = &H200
Public Const OFN_CREATEPROMPT As Long = &H2000
Public Const OFN_ENABLEHOOK As Long = &H20
Public …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用IEdmEnumeratorVariable5::SetVar
基于用户输入的一些文件卡变量更新到Windows窗体.我的代码执行,没有错误消息,文件已签出并重新签入,并将相应的注释添加到历史记录中; 但是卡上的变量不会更新.
我已经通过在运行时逐步执行代码验证所有变量都填充了正确的(如预期的)数据.该SetVar
程序的所有熄灭顺利,但在数据卡上的变量不发生改变价值-即使手动刷新文件夹视图没有影响.
以下是我的代码.
这是一个加载项应用程序,使用VS Community 2015在VB中编写为类库项目,目标框架为.NET 4.0.
努力使这个问题更简洁; 紧接着下面我只包含了设置变量工作的代码片段,然后我还包含了更多代码,以便您可以根据需要获得整个图片.
这是设置变量工作的代码:
Dim UserManager As IEdmUserMgr5 = .SourceVault
Dim User As IEdmUser5 = UserManager.GetLoggedInUser
CardComment = UserComment & CardComment
CardDate = Today().ToString("yyMMdd", Globalization.CultureInfo.InvariantCulture)
CardBy = User.Name
CardDisposition = UserDisposition
CardVariables.SetVar(DispositionVariable, "@", CardDisposition)
CardVariables.SetVar(CommentVariable, "@", CardComment)
CardVariables.SetVar(ByVariable, "@", CardBy)
CardVariables.SetVar(DateVariable, "@", CardDate)
CardVariables.Flush()
Run Code Online (Sandbox Code Playgroud)
类模块级变量:
Private Structure CommandInfo
Dim SourceVault As IEdmVault11
Dim SourceCommand As EdmCmd
Dim SourceSelection As System.Array
Dim TargetTemplate As System.String
Dim VerifiedPaths …
Run Code Online (Sandbox Code Playgroud) 我觉得我会从了解这些功能如何工作的差异中受益匪浅,这样我就可以更好地了解何时使用每个功能。
我在使用两种不同的互操作(Excel 和 EPDM)时遇到了非常困难的时间,它们都广泛使用了弱类型参数。我一直在使用返回的对象并将它们转换为正确的类型时遇到问题(根据文档)。在浪费了大量时间之后,我发现对COM 对象使用TypeName、GetType和TypeOf 运算符会产生不同的结果,并且在不同的情况下,每一个都可能比下一个更可靠或更不可靠。
现在,在大多数情况下TypeName()
,用 COM 对象确定类型似乎是最可靠的。然而,完全避免其他两个函数对我来说似乎是一种货物崇拜,除此之外,今天我遇到了一个有趣的问题,我似乎无法将对象强制转换为TypeName()
. 在对该问题的评论中提出了一个有趣的概念,即实现的对象IDispatch
实际上可能返回调度的接口类型名,这可以部分解释差异。
我真的很想更好地了解这些函数实际上是如何工作的,但是我在.NET ReferenceSource中迷失了方向,所以我在这个问题上提供了一个赏金,希望有人能解释这些不同的函数是如何工作的以及在什么应该使用每个上下文。
以下是使用 Excel 互操作的代码摘录。
Dim DocProps As Object
DocProps = WeeklyReports.CustomDocumentProperties 'WeeklyReports is a Workbook object
Debug.Print(DocProps Is Nothing)
Debug.Print(TypeName(DocProps))
Debug.Print(TypeOf (DocProps) Is DocumentProperties)
Debug.Print(DocProps.GetType.ToString)
Run Code Online (Sandbox Code Playgroud)
输出是:
虚假的
DocumentProperties
虚假的
System.__ComObject
我已经提供了我正在使用的实际代码.我试图处理的确切条件是strCurrentRev
作为零长度字符串的参数.(例如strCurrentRev=""
)
如果我注释掉错误处理语句,尝试在零长度字符串上执行ASC方法会抛出Run-Time Error 5
"无效的过程调用或参数".
如果我然后检查err.Number
它= 5.
如果我尝试使用on error resume next
active 运行完全相同的语句,则不会引发任何错误,例如在执行后err.number
总是= 0.
如果on error resume next
处于活动状态,并且您尝试从即时窗口执行ASC方法(例如,键入asc(strcurrentrev)
并命中Enter
),则会抛出运行时错误并将该err.number
属性设置为5.
我以前从未经历过这个.为什么on error resume next
激活会导致错误在正常执行中不升高???
Function NextRevLetter(strCurrentRev As String) As String
'This function returns the next revision letter given an existing revision letter.
'Declare variables
Dim lngX As Long
Dim strX As String
Dim strY As String
'First, check if we are dealing …
Run Code Online (Sandbox Code Playgroud) 我想从一系列我命名为 的向量创建一个数据框d*i*
。我尝试使用粘贴函数来执行此操作,但它只是构建了一个包含值为“d1、d2、d3...”的单列的数据框,我想将与这些变量名称关联的向量放入其中。我该怎么做这?
d1 <- c(6.3,8.3,6.6,0,8.4,8.6)
d2 <- c(8.2,8.7,8.6,7.9,7.1,7.6)
d3 <- c(7.1,6.4,6.6,8,7.5,10.3)
d4 <- c(8,7.7,7.3,0,9.4,6.4)
d5 <- c(8.5,6.8,0,0,7.3,9.7)
d6 <- c(5.9,7.5,6.5,0,9.8,7.8)
d7 <- c(7.6,5.3,6.7,0,6.6,7.4)
d8 <- c(9.5,5.6,8.8,0,8.6,8.3)
d9 <- c(8.5,7.4,0,0,9.2,8.6)
d10 <- c(7.8,6.9,8.6,6.7,6.8,6.1)
mydata <- data.frame(paste("d",1:10))
Run Code Online (Sandbox Code Playgroud)