Pass array of worksheets to ActiveX DLL (VB6)

H

Hank Scorpio

This is an esoteric one which may or may not get any responses, but
even random thoughts would be useful. (I hope that Don will forgive me
for lapsing into a cross post here, but I think that both groups are
relevant. I haven't been able to find anything on this after Googling
both the VB and Excel groups, nor anything in the KnowledgeBase.)

I'm writing a VB6 (SP6) DLL which is intended to be called from /
automate all versions of Office from 97 onwards. Objects are early
bound. In view of KB articles 244167 and 245115 (regarding the
automation of multiple versions of Office), the DLL contains a
reference to the earliest supported version of Excel; that is,
Excel8.olb. However I ran into a compile error in Excel (argument type
mismatch, described below) when I tried calling one of the library's
methods.

I created a second dummy .dll with the same Excel library reference
just to ensure that it wasn't a problem specific to the first project.
(It wasn't.) The dummy contains one class called DLLTestClass, which
has one (very simplified) method:

Function TestMethodDLL( _
xlApp As Excel.Application, _
SourceWorksheet As Excel.Worksheet, _
ByRef TargetWorksheets() As Excel.Worksheet _
) As Boolean

TestMethodDLL = False
On Error GoTo ErrorHandler

MsgBox UBound(TargetWorksheets)

TestMethodDLL = True

ExitPoint:

Exit Function

ErrorHandler:
Select Case Err.Number
Case Else
MsgBox Err.Number & vbCrLf & Err.Description

End Select

Resume ExitPoint

End Function

I compiled the dummy dll without any problem, then opened an Excel
2002 workbook, set a reference to the dll, and included the following
in a standard module:

Sub TestDLLVersion()

Dim obj As New DLLTestClass

Dim obja_wks() As Excel.Worksheet

ReDim obja_wks(1)

Set obja_wks(0) = Sheet2
Set obja_wks(1) = Sheet3

obj.TestMethodDLL Application, Sheet1, obja_wks

Set obj = Nothing

End Sub

When I run it, I get a compile error relating to the obja_wks variable
in the method call line; specifically, "ByRef Argument Type Mismatch".

If I put an identical class into the Excel workbook itself, and create
a second procedure which sets the obj variable to THAT class instead
of the dll's one, no such error occurs. This set me t'thinkin. I
therefore saved the workbook, and re-opened it in Excel 97. This time
there was no compile error in the procedure which calls the dll, and
the procedure ran perfectly.

Just to prove the point (and yes, I do have one), I changed the
reference in the dummy DLL to the Excel 10 library, recompiled it,
opened the workbook in Excel 2002, re-set the reference to the dummy
dll and... no compile error.

Conclusion: Using a reference to the oldest Office library will
generally allow you to automate that and subsequent versions... UNLESS
you're passing an array of objects from that library (or maybe just
SOME objects?), in which case you're toast unless you've specified the
library for the EXACT Office version that you're using. I've already
written a stack of methods which use all manner of individual objects;
the application object, a workbook, a worksheet, a range, a Word
document... and despite calling them from 97, 2000 AND 2002, this is
the first time I've had a problem.

Which means that I'll presumably have to kludge some unsatisfactory
workaround. (I haven't decided what yet, but I'm not crazy about the
idea of using collections, variants or generic late bound objects
since in all cases I'd need to somehow check that the passed argument
is indeed a worksheet. Which is what I was hoping to avoid, but
probably won't be able to...)

Anyone else come across this?
 
G

Gale Green

Hi.
I compiled the dummy dll without any problem, then opened an Excel
2002 workbook, set a reference to the dll, and included the following
in a standard module:

If I understand the above correctly, you are calling TestDLLVersion
from a standard module in an Excel 2002 workbook. Is that right?

It is quite correct that, when automating Office products from VB, you
should early bind:

Dim MyXL As Excel.Application
Set MyXL = New .Excel.Application
or
Set MyXL = CreateObject("Excel.Application")

On your development machine, you should have, and set a reference to,
the earliest version of the Office product that you want your app to
work with.

However, that is Automation from VB. Passing a parameter from another
version of Excel, I suspect, is a different kettle of fish.
TestDLLVersion's arguments are probably being set up to expect an
Excel 8 object, hence the failure when passing in a Workbook reference
from Excel 2002.

You could try declaring TestDLLVersion's arguments as Object instead
of Excel.Worksheet.

You can still use early binding within the Sub:

Dim MySheet As Excel.Worksheet
Set MySheet = TargetWorksheets(n)
....
Set MySheet = Nothing

You may get a more useful response from an Excel newsgroup.

Gale.
 
H

Hank Scorpio

I compiled the dummy dll without any problem, then opened an Excel
2002 workbook, set a reference to the dll, and included the following
in a standard module:
If I understand the above correctly, you are calling TestDLLVersion
from a standard module in an Excel 2002 workbook. Is that right?
Correct.

[Snip]
On your development machine, you should have, and set a reference to,
the earliest version of the Office product that you want your app to
work with.

However, that is Automation from VB. Passing a parameter from another
version of Excel, I suspect, is a different kettle of fish.
TestDLLVersion's arguments are probably being set up to expect an
Excel 8 object, hence the failure when passing in a Workbook reference
from Excel 2002.

That's not the problem. As I mentioned later in the original post, I
have no problems passing individual workbook objects, worksheet
objects, Word documents or any other single objects from an Office
application to the library, regardless of which version of Office I'm
passing them from. The problem only occurs when I'm attempting to pass
an ARRAY of objects, specifically (in this case) worksheets.
You could try declaring TestDLLVersion's arguments as Object instead
of Excel.Worksheet.

Thanks for the suggestion; I may end up needing to do that. As I
mentioned later in my original post though, that's a matter of last
resort because I don't want to have to also test each member of the
array to ensure that it's the right type of object.
You can still use early binding within the Sub:

Dim MySheet As Excel.Worksheet
Set MySheet = TargetWorksheets(n)
...
Set MySheet = Nothing

This is still dealing with only a single sheet at a time, though, and
that's something that I have no problem with.
You may get a more useful response from an Excel newsgroup.

That's why this has been cross-posted to Excel.Programming. (The Excel
groups are my "home territories" (even if I've been a little lax of
late), but this problem seems to fall into both camps.)

I appreciate your time.
 
B

Beeeeeeeeeeeeves

Objects are early
bound.
Why?
I compiled the dummy dll without any problem, then opened an Excel
2002 workbook, set a reference to the dll, and included the following
in a standard module:

Sub TestDLLVersion()

Dim obj As New DLLTestClass

Dim obja_wks() As Excel.Worksheet

ReDim obja_wks(1)

Set obja_wks(0) = Sheet2
Set obja_wks(1) = Sheet3

obj.TestMethodDLL Application, Sheet1, obja_wks

Set obj = Nothing

End Sub

When I run it, I get a compile error relating to the obja_wks variable
in the method call line; specifically, "ByRef Argument Type Mismatch".

I wouldn't be surprised.
If I put an identical class into the Excel workbook itself, and create
a second procedure which sets the obj variable to THAT class instead
of the dll's one, no such error occurs. This set me t'thinkin. I
therefore saved the workbook, and re-opened it in Excel 97. This time
there was no compile error in the procedure which calls the dll, and
the procedure ran perfectly.

Don't waste your time on this early binding confusion.
Just to prove the point (and yes, I do have one), I changed the
reference in the dummy DLL to the Excel 10 library, recompiled it,
opened the workbook in Excel 2002, re-set the reference to the dummy
dll and... no compile error.

Conclusion: Using a reference to the oldest Office library will
generally allow you to automate that and subsequent versions... UNLESS
you're passing an array of objects from that library (or maybe just
SOME objects?), in which case you're toast unless you've specified the
library for the EXACT Office version that you're using. I've already
written a stack of methods which use all manner of individual objects;
the application object, a workbook, a worksheet, a range, a Word
document... and despite calling them from 97, 2000 AND 2002, this is
the first time I've had a problem.

Which means that I'll presumably have to kludge some unsatisfactory
workaround. (I haven't decided what yet, but I'm not crazy about the
idea of using collections, variants or generic late bound objects
since in all cases I'd need to somehow check that the passed argument
is indeed a worksheet.

Why would you NEED to check it's a worksheet? If anyone passes it an object that isn't a worksheet (and to be honest, you can probably stop flattering yourself that everyone in your office is going to be clamouring for a copy of this DLL - in all probability you'll be the only one that uses it) they'll just get a slightly different error a bit further down the line ( a few lines of code on)....
Which is what I was hoping to avoid, but
probably won't be able to...)

No, you probably won't be able to avoid it. This IS what late binding was invented for.
 
G

Gale Green

That's not the problem. As I mentioned later in the original post, I
have no problems passing individual workbook objects, worksheet
objects, Word documents or any other single objects from an Office
application to the library, regardless of which version of Office I'm
passing them from. The problem only occurs when I'm attempting to pass
an ARRAY of objects, specifically (in this case) worksheets.

I did realise that. It is still quite likely that array arguments are
set up differently from scalar arguments.
This is still dealing with only a single sheet at a time, though, and
that's something that I have no problem with.

I was presuming that you were processing the array one element at a
time:

Function TestMethodDLL(... TargetWorksheets() As Object)...

Dim MySheet As Excel.Worksheet

For n = LBound(TargetWorksheets) To UBound(TargetWorksheets)

Set MySheet = TargetWorksheets(n)
' Process MySheet
Set MySheet = Nothing

Next

Sorry I can't be more helpful.

Gale.
 
H

Hank Scorpio


Because it makes development easier and less error-prone for starters.
Because it allows you to specify the types of objects that properties
and methods require, thus making it easier for people using your
objects to detect, at compilation time, when they've passed an
invalid argument type for seconds. For thirds... never mind. You'll
find the other reasons in most programming textbooks. On on MSDN. Or
in other places that require some reading.

[Snip the code, since you had nothing worthwhile to say about it.]
Don't waste your time on this early binding confusion.

Gee thanks. That's useful. You really must sign on as a consultant to
the many and varied textbook writers who point out the benefits of
early binding when you're working with *known* object types.
Why would you NEED to check it's a worksheet?

Good point. There's no need for all this error checking and
interception. I think I'll just go and redefine all of my variables as
Variant too. Better still, I'll just rip out the Option Explicit
statements and use implicit declarations. Let the errors fall where
they may!
If anyone passes it an object
that isn't a worksheet (and to be honest, you can probably stop flattering yourself
that everyone in your office is going to be clamouring for a copy of this DLL

Gee, thanks again, that's just so constructive. You don't think that
possibly, just maybe, I'll have a better idea than you of the 247 end
users in our various branches who will have the .dll installed when
it's finished than you will, hmm?

Yes, I concur with anyone else reading this; I don't know why I
bothered replying to it either. I think the expression I'm looking for
is [Plonk].
 
B

Beeeeeeeeeeeeves

Because it makes development easier and less error-prone for starters.

Development isn't supposed to be orienteated towards making other development easier, the ultimate aim is supposed to be to produce a good, final application for the end user. That's the *END* user, not just the person who you consider to be your customer.
Because it allows you to specify the types of objects that properties
and methods require, thus making it easier for people using your
objects to detect, at compilation time, when they've passed an
invalid argument type for seconds.

I agree that this is a good advantage to make use of, but it shouldn't EVER be at the expense of cross-version incompatibility.
A developer that is using a DLL which takes an object as a parameter should know to use the DLL's documentation to know what type of object that should take. If you're so thick you're too scared of losing intellisense, maybe you should get a job as a bank teller.
Gee thanks. That's useful. You really must sign on as a consultant to
the many and varied textbook writers who point out the benefits of
early binding when you're working with *known* object types.

But as you've said yourself, they're not known when you're using multiple different versions of the applicaiton.... (which in this case is Excel), but you blindly carry on doing it regardless... "I MUST have intellisense!" you fuucking cretin!
Good point. There's no need for all this error checking and
interception. I think I'll just go and redefine all of my variables as
Variant too.

Don't be sarcy, you know exactly what I mean (and what's more you're riled because you know I'm right - you just don't want to lose the buzz you get when intellisense works on your own DLL) - a long is always going to be a long no matter how many new versions of Excel are brought out. But an Excel.Workbook array won't be. It will have a different guid, but the same type name ("excel.workbook") as an Excel.Workbook.9. And you know it.


statements and use implicit declarations. Let the errors fall where
they may!

Like i say if you're so thick that you blindly go ahead and insist on the need for type checking even when it breaks version compatability then you shouldn't be a programmer.

Gee, thanks again, that's just so constructive. You don't think that
possibly, just maybe, I'll have a better idea than you of the 247 end
users in our various branches who will have the .dll installed when
it's finished than you will, hmm?

Maybe you do. Do you have a sense of doom and gloom that they're even more stupid than you are? After all what sort of a company can it be, when YOU of all people have attained the heady hights of "senior DLL writer"?
HAVEN'T YOU HEARD OF DOCUMENTATION?

(Tit.)
 
R

Rick Rothstein

But as you've said yourself, they're not known when you're using
multiple different versions of the applicaiton.... (which in this case
is Excel), but you blindly carry on doing it regardless... "I MUST have
intellisense!" you f***ing cretin!
Maybe you do. Do you have a sense of doom and gloom that they're even
more stupid than you are? After all what sort of a company can it be,
when YOU of all people have attained the heady hights of "senior DLL
writer"?
HAVEN'T YOU HEARD OF DOCUMENTATION?

Ease up there Ben... the vulgar word is completely out of place here
(remember, younger programmers come here for help also) and the name
calling is not real cool either. I guess we could say you are not having
a good day today. Maybe you might want to take a break for a day or two
until you get your bearings back.

Rick
 
B

Beeeeeves

Ease up there Ben... the vulgar word is completely out of place here

Usenet filters out swear words, so there shouldn't be any reason for
something I type to get through. If they want to outwit me, they'll have to
use a regex then won't they - possibly <regex type="air" tested="false>
"f+\s*u+\s*c+\s*k" </regex> ?
If a post matches that then it's vulgar. I'll leave it up to you to
construct a function which takes a string array of defined swear words and
come up with a load of regexes (or a single one ;-) ) to eliminate any
variation on them. And I expect optimization.
(remember, younger programmers come here for help also)

I AM one of the younger programmers - how old did you think I was??!! 40?

Tip - if you want to killfile me, notice that I only ever have two different
names, Beeeeeeeves probably has a different amount of "e"s in it when I'm at
work to when I'm at home. I do change the fake mail address from time to
time, basically because it's easy and it pisses Bob O'Bob off.

I haven't felt "cool" since my mind was mullered in summer 2002, so there's
no love lost there I'm afraid.
 
R

Rick Rothstein

Ease up there Ben... the vulgar word is completely out of place here
Usenet filters out swear words, so there shouldn't be any reason for
something I type to get through. If they want to outwit me, they'll have to
use a regex then won't they - possibly <regex type="air" tested="false>
"f+\s*u+\s*c+\s*k" </regex> ?
If a post matches that then it's vulgar. I'll leave it up to you to
construct a function which takes a string array of defined swear words and
come up with a load of regexes (or a single one ;-) ) to eliminate any
variation on them. And I expect optimization.


I AM one of the younger programmers - how old did you think I was??!! 40?

Tip - if you want to killfile me, notice that I only ever have two different
names, Beeeeeeeves probably has a different amount of "e"s in it when I'm at
work to when I'm at home. I do change the fake mail address from time to
time, basically because it's easy and it pisses Bob O'Bob off.

I haven't felt "cool" since my mind was mullered in summer 2002, so there's
no love lost there I'm afraid.

I have no desire to killfile you... when you decide to buckle down and
actually answer questions, I find them interesting and illuminating to
read. It's just when you get into these "the hell with helping people
moods" (you are bored, I presume), you sometimes tend to go overboard.
Calling people names seems childish (maybe you **are** a lot younger
than I give you credit for<g>). As for usenet filters, I'm not too sure
about them, but the f***ing word came through unmodified in your post.

Rick
 
H

Hank Scorpio

I AM one of the younger programmers - how old did you think I was??!! 40?

Believe me, that came through in your original post.
Tip - if you want to killfile me, notice that I only ever have two different
names,

Thanks for the tip. I've now bozo binned this one as well.
 
B

Beeeeeeeeeeeeves

So, presumably you can killfile on name aswell as email address?
In that case I'll have to put a few more "e"s in now and again...
 
J

Jamie Collins

Hank Scorpio said:
I'm not crazy about the
idea of using collections, variants or generic
late bound objects since in all cases I'd need
to somehow check that the passed argument
is indeed a worksheet.

How about using your own custom class collection class that wraps the
collection object and only allows Excel.Worksheet objects in? e.g.

' --- Revised code in DLLTestClass
Option Explicit

Public Function TestMethodDLL( _
xlApp As Excel.Application, _
SourceWorksheet As Excel.Worksheet, _
ByRef TargetWorksheets As CWorksheets _
) As Boolean

TestMethodDLL = False
On Error GoTo ErrorHandler

MsgBox TargetWorksheets.Count

TestMethodDLL = True

ExitPoint:

Exit Function

ErrorHandler:
Select Case Err.Number
Case Else
MsgBox Err.Number & vbCrLf & Err.Description

End Select

Resume ExitPoint

End Function


' --- Code in new CWorksheets class (in VB6 project)
Option Explicit

Private m_colWorksheets As Collection

Public Property Get Item(ByVal Index As Variant) As Excel.Worksheet
Set Item = m_colWorksheets.Item(Index)
End Property

Public Property Get NewEnum() As IUnknown
Set NewEnum = m_colWorksheets.[_NewEnum]
End Property

Public Sub Add(ByVal ExcelWorksheet As Excel.Worksheet)
m_colWorksheets.Add ExcelWorksheet, ExcelWorksheet.Name
End Sub

Public Property Get Count() As Long
Count = m_colWorksheets.Count
End Property

Public Function Remove(ByVal Index As Variant) As Boolean
On Error Resume Next
m_colWorksheets.Remove Index
Remove = CBool(Err.Number = 0)
End Function

Private Sub Class_Initialize()
Set m_colWorksheets = New Collection
End Sub


' --- Code in Excel standard module
Option Explicit

Sub TestDLLVersion()

Dim obj As New DLLTestClass

Dim obja_wks As CWorksheets
Set obja_wks = New CWorksheets

obja_wks.Add Sheet3
obja_wks.Add Sheet2

obj.TestMethodDLL Application, Sheet1, obja_wks

Set obj = Nothing

End Sub

Jamie.

--
 
J

Jamie Collins

Hank Scorpio said:
I'm not crazy about the
idea of using collections, variants or generic
late bound objects since in all cases I'd need
to somehow check that the passed argument
is indeed a worksheet.

How about using your own custom class collection class that wraps the
collection object and only allows Excel.Worksheet objects in? e.g.

' --- Revised code in DLLTestClass
Option Explicit

Public Function TestMethodDLL( _
xlApp As Excel.Application, _
SourceWorksheet As Excel.Worksheet, _
ByRef TargetWorksheets As CWorksheets _
) As Boolean

TestMethodDLL = False
On Error GoTo ErrorHandler

MsgBox TargetWorksheets.Count

TestMethodDLL = True

ExitPoint:

Exit Function

ErrorHandler:
Select Case Err.Number
Case Else
MsgBox Err.Number & vbCrLf & Err.Description

End Select

Resume ExitPoint

End Function


' --- Code in new CWorksheets class (in VB6 project)
Option Explicit

Private m_colWorksheets As Collection

Public Property Get Item(ByVal Index As Variant) As Excel.Worksheet
Set Item = m_colWorksheets.Item(Index)
End Property

Public Property Get NewEnum() As IUnknown
Set NewEnum = m_colWorksheets.[_NewEnum]
End Property

Public Sub Add(ByVal ExcelWorksheet As Excel.Worksheet)
m_colWorksheets.Add ExcelWorksheet, ExcelWorksheet.Name
End Sub

Public Property Get Count() As Long
Count = m_colWorksheets.Count
End Property

Public Function Remove(ByVal Index As Variant) As Boolean
On Error Resume Next
m_colWorksheets.Remove Index
Remove = CBool(Err.Number = 0)
End Function

Private Sub Class_Initialize()
Set m_colWorksheets = New Collection
End Sub


' --- Code in Excel standard module
Option Explicit

Sub TestDLLVersion()

Dim obj As New DLLTestClass

Dim obja_wks As CWorksheets
Set obja_wks = New CWorksheets

obja_wks.Add Sheet3
obja_wks.Add Sheet2

obj.TestMethodDLL Application, Sheet1, obja_wks

Set obj = Nothing

End Sub

Jamie.

--
 
S

Stephen Bullen

Hi Hank,
However I ran into a compile error in Excel (argument type
mismatch, described below) when I tried calling one of the library's
methods.

I've been burnt passing arrays of non-simple types between Excel and
VB6 dlls too and always assumed it's COM's marshalling getting in the
way. My suggestion would be to make it easy on the users of the DLL by
defining the object As Variant and allowing them to pass a single
sheet, array of sheets, collection of sheets or an Excel Sheets object:

Function TestMethodDLL( _
xlApp As Excel.Application, _
SourceWorksheet As Excel.Worksheet, _
ByRef TargetWorksheets As Variant _
) As Boolean

Dim vItem As Variant
Dim oSht As Excel.Worksheet

TestMethodDLL = False
On Error GoTo ErrorHandler

'Just one sheet?
If TypeName(TargetWorksheets) = "Worksheet" Then
Set oSht = TargetWorksheets
MsgBox oSht.Name

'An array, Collection or Sheets object?
ElseIf IsArray(TargetWorksheets) Or _
TypeName(TargetWorksheets) = "Collection" Or _
TypeName(TargetWorksheets) = "Sheets" Then

'Loop through them, checking for worksheets
For Each vItem In TargetWorksheets
If TypeName(vItem) = "Worksheet" Then
Set oSht = vItem
MsgBox oSht.Name
End If
Next
End If

TestMethodDLL = True

ExitPoint:

Exit Function

ErrorHandler:
Select Case Err.Number
Case Else
MsgBox Err.Number & vbCrLf & Err.Description

End Select

Resume ExitPoint

End Function


Tested using the following Excel code:

Sub TestDLLVersion()

Dim obj As New class1
Dim col As Collection
Dim obja_wks() As Excel.Worksheet

'A single sheet
obj.TestMethodDLL Application, Sheet1, Sheet2

'An array of sheets
ReDim obja_wks(1)
Set obja_wks(0) = Sheet2
Set obja_wks(1) = Sheet3
obj.TestMethodDLL Application, Sheet1, obja_wks

'A collection of sheets
Set col = New Collection
col.Add Sheet2
col.Add Sheet3
obj.TestMethodDLL Application, Sheet1, obja_wks

'An Excel Sheets collection
obj.TestMethodDLL Application, Sheet1, ActiveWindow.SelectedSheets

Set obj = Nothing

End Sub


Regards

Stephen Bullen
Microsoft MVP - Excel
www.BMSLtd.ie
 
B

Beeeeeeeeeeeeves

Because it doesn't solve his problem. It's still early bound, and he'd need to recompile the DLL that contained the custom collection for each version of Excel, etc.. which is what the point of the question was.

Mine solves that, he just doesn't want to admit it.


Jamie Collins said:
Hank Scorpio said:
I'm not crazy about the
idea of using collections, variants or generic
late bound objects since in all cases I'd need
to somehow check that the passed argument
is indeed a worksheet.

How about using your own custom class collection class that wraps the
collection object and only allows Excel.Worksheet objects in? e.g.

' --- Revised code in DLLTestClass
Option Explicit

Public Function TestMethodDLL( _
xlApp As Excel.Application, _
SourceWorksheet As Excel.Worksheet, _
ByRef TargetWorksheets As CWorksheets _
) As Boolean

TestMethodDLL = False
On Error GoTo ErrorHandler

MsgBox TargetWorksheets.Count

TestMethodDLL = True

ExitPoint:

Exit Function

ErrorHandler:
Select Case Err.Number
Case Else
MsgBox Err.Number & vbCrLf & Err.Description

End Select

Resume ExitPoint

End Function


' --- Code in new CWorksheets class (in VB6 project)
Option Explicit

Private m_colWorksheets As Collection

Public Property Get Item(ByVal Index As Variant) As Excel.Worksheet
Set Item = m_colWorksheets.Item(Index)
End Property

Public Property Get NewEnum() As IUnknown
Set NewEnum = m_colWorksheets.[_NewEnum]
End Property

Public Sub Add(ByVal ExcelWorksheet As Excel.Worksheet)
m_colWorksheets.Add ExcelWorksheet, ExcelWorksheet.Name
End Sub

Public Property Get Count() As Long
Count = m_colWorksheets.Count
End Property

Public Function Remove(ByVal Index As Variant) As Boolean
On Error Resume Next
m_colWorksheets.Remove Index
Remove = CBool(Err.Number = 0)
End Function

Private Sub Class_Initialize()
Set m_colWorksheets = New Collection
End Sub


' --- Code in Excel standard module
Option Explicit

Sub TestDLLVersion()

Dim obj As New DLLTestClass

Dim obja_wks As CWorksheets
Set obja_wks = New CWorksheets

obja_wks.Add Sheet3
obja_wks.Add Sheet2

obj.TestMethodDLL Application, Sheet1, obja_wks

Set obj = Nothing

End Sub

Jamie.
 
P

PaulS

Frank, not sure if you're interested but we actually
employ people like this. Combination of quite bright but
no sense at all and very immature. Over the years we have
developed a strategy - something like this:

Keep separated from others and allow them to plod away at
the clever stuff, steering where necessary in such a way
that whatever becomes their own idea.
Listen to what they say in case amidst the nonsense
something useful emerges. If nothing does just humour them
politely without rising, control constructive argument but
avoid futile debate. This is all rather a black art.

We tend to find most begin to catch on and we can all look
back and laugh at their former ways. The first tangible
sign is when they start learning how to listen (can be a
new concept for them), the transformation is satisfying to
watch. But some never will, for these and similar who
cross our path, we give a gesture of dismissal - of the
ancient kind.

Paul
 
S

Stephen Bullen

Hi Beeeeeeeeeeeeves,
Because it doesn't solve his problem. It's still early bound, and he'd need to recompile the DLL that contained the custom collection for each
version of Excel, etc.. which is what the point of the question was.

Actually, no. I presume you haven't tried Jamie's suggestion. The Excel object library is extraordinarily good at backwards-compatibility. In
general, one can reference the earliest version of Excel in the DLL and it will 'just work' when used from later versions, without recompiling and
all early bound. Passing arrays of worksheets seems to be one of the extremely few exceptions to the 'just works' rule, for which there are a
number of workarounds - and creating your own Worksheets collection class is certainly one of them.

Regards

Stephen Bullen
Microsoft MVP - Excel
www.BMSLtd.ie
 
B

Beeeeeves

Wrong.

Stephen Bullen said:
Hi Beeeeeeeeeeeeves,
need to recompile the DLL that contained the custom collection for each
version of Excel, etc.. which is what the point of the question was.

Actually, no. I presume you haven't tried Jamie's suggestion. The Excel
object library is extraordinarily good at backwards-compatibility. In
general, one can reference the earliest version of Excel in the DLL and it
will 'just work' when used from later versions, without recompiling and
all early bound. Passing arrays of worksheets seems to be one of the
extremely few exceptions to the 'just works' rule, for which there are a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top