I have a line of code I need to compile into a (ActiveX) DLL in VB6, unfortunately I am always greeted with a, "Declare statements not allowed as public members of object modules".
The line looks like this:
Public Declare Sub Example Lib "kernel32"
Is there any work around? I saw somewhere you can do this with, Property Set, or Property Let. I'm just not sure how. Any help would be appreciated.
Thanks.
See if this works for you:
Private Declare Sub Example Lib "kernel32"
Public Sub CallExample()
Call Example
End Sub
Here is a MSFT reference that gives more info:
http://msdn.microsoft.com/en-us/library/office/gg278767.aspx
Related
I have a library called PIT_math_tools (written in vb.net) containing math functions which is split up into different modules.
In this case, the function I want to access is located in a Module called geometry_ellipsen_module:
Namespace geometry_ellipsen
Public Module geometry_ellipsen_module
...
Public Function calc_distanz_ellipse_kreis(...) As Double
Now I want to access the Function calc_distanz_ellipse_kreis() in VBA.
I used the following declare statement to accomplish this:
Private Declare PtrSafe Function calc_distanz_ellipse_kreis Lib "C:\Users\path...\PIT_math_tools.dll" (...) As Double
So far, everything looks fine.
When trying to call that function, however, I get runtime error '453'
"DLL-Entry Point calc_distanz_ellipse_kreis in 'PathToLibrary' not found."
When using the function in other .Net code, it could be found either by using the prefix
PIT_math_tools.geometry_ellipsen.geometry_ellipsen_module.calc_distanz_ellipse_kreis()
or an import statement identical to the prefix above.
Based on that, I tried extending the Function name in the Declare Statement by the same prefix:
Private Declare PtrSafe Function geometry_ellipsen.geometry_ellipsen_module.calc_distanz_ellipse_kreis Lib ...
However, this results in a compiler error "Expected: Lib".
How do I get the vba code to find the function inside the library module?
Thanks in advance.
The VBA syntax...
Private Declare Function SomeMethod() Lib "Some.dll"
... is used to prototype standard Win32 DLLs, e.g. Win32 API. Which .NET DLLs (aka "Assemblies") are not.
What you need to do in VB.NET is to make that assembly COM-visible. VB.NET creates a typelib (*.tlb) for the assembly.
In VBA you then add a COM reference (point to that typelib) to your project like you would do with other COM DLLs (ADODB, MSXML etc.). And then you do your standard
Dim myObject As Namespace.ClassName
Set myObject = New Namespace.ClassName
With myObject
.ThisProperty = 123
Dim lRet As Long
lRet = .ThisMethod("abc")
End With
I have some complex code which takes some user inputs (names of shapes to copy) then copies said shapes from one sheet to another multiple times. The items are grouped shapes drawn in Excel and all named correctly and uniquely.
I receive copy and paste errors intermittently "Method 'Paste' of object _Worksheet' failed" and "Method 'copy' Of Object '_worksheet' Failed. Through researching the problem we understand that it is fairly common and has something to do with programmes which conflict with Excel when they are accessing the clipboard.
So far, my colleague and I have deduced that 2 programmes in particular interfere the most with the copy/paste operations - Adobe Reader and Autodesk Powershape. (Autodesk and Adobe both have Reference Libraries available within VBA, not sure if this is a coincidence?)
The problem used to occur very frequently whilst we had the programmes open, so we wrote the following macros/functions to try and stablise the code:-
Public Sub CopyShape(ItemName, CopyDestination)
Call ClearClipboard Sheets(CopyDestination).Shapes(ItemName).Copy
Do Until IsClipboardEmpty = False DoEvents Loop
End Sub
Where "ClearClipboard" is:-
Public Function ClearClipboard()
OpenClipboard (0&)
EmptyClipboard
CloseClipboard
End Function
and the function IsClipboardEmpty is:-
Function IsClipboardEmpty() As Boolean
IsClipboardEmpty = (CountClipboardFormats() = 0)
End Function
with the following public declarations:-
Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Declare Function EmptyClipboard Lib "user32" () As Long
Declare Function CloseClipboard Lib "user32" () As Long
Public Declare Function CountClipboardFormats Lib "user32" () As Long
This code works quite a lot of the time (far better than trying to use "DoEvents" after the copy operation which just failed miserably) as it forces the code to check if the copied item is in the clipboard before trying to paste it, but it doesn't always work - something in the background still messes up the code.
Is there any way of either:-
locking and unlocking the clipboard using VBA or APIs?
using a completely different method of copying and pasting the shapes?
Any and all solutions welcome and of course happy to answers any questions.
Thanks
In many of my .NET projects I declare library functions that are used globally. The DLLs that contain these functions are registered when the product is installed so the declaration is simple:
eg.
Declare Sub SomeFunction Lib "SomeLib.dll" (ByVal CommonStr As String, ByVal
WhichVar As Integer)
However, when I'm debugging/developing I often need to explicitly reference the path of the dll like this:
Declare Sub SomeFunction Lib "C:\Usethisone\SomeLib.dll" (ByVal CommonStr As String, ByVal
WhichVar As Integer)
My problem is that I have occasionally forgotten to remove the file path when sending the code to QA so it gets sent back.
So, how can I code this so I don't need to remember to change this path every time I send a project out for testing? The Declares, of course, are in the declaration section of the class so I can't use any If logic to switch declarations ( eg. If testingfile.txt Exists then use testing declaration).
I've also thought of creating a global dll that I could inherit from - one with the production declarations and one with the testing declarations - but that is a major change at a low level. I'm afraid it either just wouldn't work, would cause reference issues and/or would not be approved by management.
Any simpler ideas out there?
You can use Conditional Compilation in Visual Basic
#If DEBUG
Declare Sub SomeFunction Lib "C:\Usethisone\SomeLib.dll" (ByVal CommonStr As String, _
ByVal WhichVar As Integer)
#Else
Declare Sub SomeFunction Lib "SomeLib.dll" (ByVal CommonStr As String, _
ByVal WhichVar As Integer)
#End If
If you use the Debug configuration, you get the code for development, if you use the Release configuration you get the production version of the code.
Note that the #If is evaluated at compile time, not at runtime. Only the matching code is compiled. The other one is discarded.
See also: #If...Then...#Else Directives.
In VB.NET as in C# you can use the preprocessor directive #if...#else...#end if to declare two different versions of your dll, one for the DEBUG compilation and one for the RELEASE compilation
#if DEBUG Then
Declare Sub SomeFunction Lib "C:\Usethisone\SomeLib.dll" (ByVal CommonStr As String, ByVal
WhichVar As Integer)
#else
Declare Sub SomeFunction Lib "SomeLib.dll" (ByVal CommonStr As String, ByVal
WhichVar As Integer)
#end if
Now when you compile to send your app to the QA you just switch to Release and you have the correct implementation to send
Side note: Take a look at the difference between Declare and the DllImport attribute
I need a VBA millisecond (~100) delay timer and tried using the API:
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Then use Sleep(100) in a sub.
But, when I try using it I get a compiler error:
"Constants, fixed-length strings, arrays, user-defined types and
declare statements not allowed as Public members of object modules"
I get the same error if I change it to 'Private'.
Any clues as to how I can get this to work?
Thanks for any help provided.
The relevant part of the error is this (emphasis mine):
"Constants, fixed-length strings, arrays, user-defined types and
declare statements not allowed as Public members of object modules"
In other words, you apparently can't have a Public Declare statement in a class module.
Add a new standard/procedural (.bas) module, and move the Declare statement(s) there. Or, make it Private if that's the only module it's used in.
Should "just work" ;-)
I'm having some trouble finding the syntax for making function calls to unmanaged DLLs in VB.NET. Is anyone familiar with this?
Let's just assume there's a function "Connected" in unmanaged DLL "Connector.DLL". I want to call this function by creating an abstract function call to it.
I've seen some code out there that looks something like
[DllImport("Connector.DLL")]
Public Shared Function Connect(ByVal intPort)
But that syntax doesn't work for me.
Try the following code.
Public Declare Function Connect Lib "Connector.DLL" (<MarshalAs(UnmanagedType.I4)> ByVal intPort As Integer) As Integer
In Visual Studio, add a reference to this Dll.
In Code:
Dim vr as new COMDllClass()
vr.FunctionInDll()
EDIT per comment:
Try this code:
<DllImport("Connector.DLL")> _
Public Shared Function Connect(ByVal intPort)