vba cast variant listbox / Objects - vba

I got an issue with "casting" variants to defined objects.
At runtime my variant variable is of type "Variant/Object/Listbox", which i then want to set to a ListBox variable to route it as a parameter to another function (GetSelected) that requires a Listbox object.
But I get the error 13: types incompatible on command "Set lst = v".
Any ideas how to get it working?
Code:
Function GetEditableControlsValues(EditableControls As Collection) As Collection
'Gibt die Werte der editierbaren Felder zurück.
Dim v As Variant
Dim coll As New Collection
Dim lst As ListBox
For Each v In EditableControls
If TypeName(v) = "ListBox" Then
Set lst = v 'Fehler 13: Typen unverträglich. v zur Laufzeit: Variant/Object/Listbox.
coll.Add GetCollectionString(GetSelected(lst))
Else
coll.Add v.Value
End If
Next
End Function

This is what I have so far:
Imagine that you have a module with the following code in it:
Option Explicit
Public Sub TestMe()
Dim colInput As New Collection
Dim colResult As Collection
Dim lngCount As Long
Dim ufMyUf As UserForm
Set ufMyUf = UserForm1
Set colInput = GetListBoxObjects(ufMyUf)
For lngCount = 1 To colInput.Count
Debug.Print colInput(lngCount).Name
Next lngCount
End Sub
Function GetListBoxObjects(uf As UserForm) As Collection
Dim colResult As New Collection
Dim objObj As Object
Dim ctrCont As Control
For Each ctrCont In uf.Controls
If LCase(Left(ctrCont.Name, 7)) = "listbox" Then
Set objObj = ctrCont
colResult.Add objObj
End If
Next ctrCont
Set GetListBoxObjects = colResult
End Function
If you run TestMe, you would get a collection of the ListBox objects. Anyhow, I am not sure how do you pass them to the collection function, thus I have decided to iterate over the UserForm and thus to check all of the objects on it.
Cheers!

I had problems with casting controls myself and didn't find a general solution that I could use easy.
Eventually I found the way to do it: store as "Object" makes it easy to convert to whatever type the control actually is.
I tested (and use) it
The sub below shows that it works (here : 1 TextBox; 1 ListBox; 1 ComboBox; 1 CommandButton on a worksheet)
Sub Test_Casting()
Dim lis As MSForms.ListBox
Dim txt As MSForms.TextBox
Dim btn As MSForms.CommandButton
Dim com As MSForms.ComboBox
Dim numObjects As Integer: numObjects = Me.OLEObjects.Count
Dim obj() As Object
ReDim obj(1 To numObjects) As Object
Dim i As Integer: i = 0
Dim cttl As OLEObject
For Each ctrl In Me.OLEObjects
i = i + 1
Set obj(i) = ctrl.Object
Next ctrl
Dim result As String
For i = 1 To numObjects
If TypeOf obj(i) Is MSForms.ListBox Then
Set lis = obj(i): result = lis.Name
ElseIf TypeOf obj(i) Is MSForms.TextBox Then
Set txt = obj(i): result = txt.Name
ElseIf TypeOf obj(i) Is MSForms.CommandButton Then
Set btn = obj(i): result = btn.Name
ElseIf TypeOf obj(i) Is MSForms.ComboBox Then
Set ComboBox = obj(i): result = com.Name
Else
result = ""
End If
If (Not (result = "")) Then Debug.Print TypeName(obj(i)) & " name= " & result
Next i
For i = 1 To numObjects
Set lis = IsListBox(obj(i))
Set txt = IsTextBox(obj(i))
Set btn = IsCommandButton(obj(i))
Set com = IsComboBox(obj(i))
result = ""
If (Not (lis Is Nothing)) Then
result = "ListBox " & lis.Name
ElseIf (Not (txt Is Nothing)) Then
result = "TexttBox " & txt.Name
ElseIf (Not (btn Is Nothing)) Then
result = "CommandButton " & btn.Name
ElseIf (Not (com Is Nothing)) Then
result = "ComboBox " & com.Name
End If
Debug.Print result
Next i
End Sub
Function IsListBox(obj As Object) As MSForms.ListBox
Set IsListBox = IIf(TypeOf obj Is MSForms.ListBox, obj, Nothing)
End Function
Function IsTextBox(obj As Object) As MSForms.TextBox
Set IsTextBox = IIf(TypeOf obj Is MSForms.TextBox, obj, Nothing)
End Function
Function IsComboBox(obj As Object) As MSForms.ComboBox
Set IsComboBox = IIf(TypeOf obj Is MSForms.ComboBox, obj, Nothing)
End Function
Function IsCommandButton(obj As Object) As MSForms.CommandButton
Set IsCommandButton = IIf(TypeOf obj Is MSForms.CommandButton, obj, Nothing)
End Function
One use for it is a class for handling events in one class.
Private WithEvents intEvents As IntBoxEvents
Private WithEvents decEvents As DecBoxEvents
Private genEvents As Object
Private genControl as OLEobject
Public sub Delegate(ctrl As OLEObject)
set genControl = ctrl
' Code for creating intEvents or decEvents
if .... create intevents.... then set genEvents = new IntEvents ' pseudo code
if .... create decevents.... then set genEvents = new DecEvents ' pseudo code
end sub
I hope this helps others that struggle with casting controls

Related

How to loop through text boxes and verify if there are duplicate values?

I'm trying to setup a function that sends a mail to a defined list of recipients.
Each recipient is fetched from a textbox. The problem is that I want to identify if there are any duplicate values and exclude them when sending the email.
As an example, if textbox1 has the same value as textbox2, don't include textbox1 value in the recipients list.
I've tried with the following sub
Private Sub CheckDuplicates()
Dim x As Long
Dim y As Long
Dim User() As TextBox = {Mail_user1, Mail_user2, Mail_user3, Mail_user4, Mail_user5, Mail_user6, Mail_user7, Mail_user8, Mail_user9, Mail_user10, Mail_user11, Mail_user12, Mail_user13, Mail_user14, Mail_user15, Mail_user16, Mail_user17, Mail_user18, Mail_user19, Mail_user20, Mail_user21, Mail_user22, Mail_user23, Mail_user24, Mail_user25, Mail_user26, Mail_user27, Mail_user28, Mail_user29, Mail_user30}
For x = 1 To 30 - 1
For y = x + 1 To 30
If User(x).Text = User(y).Text Then
User(y).Text = ""
End If
Next
Next
End Sub
The issue is that I get the following error when I want to send the mail:
Index was outside the bounds of the array.
And the mail sub looks like this:
Public Function AddRecipients(mail As outlook.MailItem) As Boolean
Dim retValue As Boolean = False
Dim recipients As outlook.Recipients = Nothing
Dim recipientTo As outlook.Recipient = Nothing
Dim recipientCC As outlook.Recipient = Nothing
Dim recipientBCC As outlook.Recipient = Nothing
Try
recipients = mail.Recipients
' check if there are any recipients and remove them
While recipients.Count > 0
recipients.Remove(1)
End While
' new recipients list
CheckDuplicates()
'------------------CC section---------------------------
recipientCC = recipients.Add("someemail#test.com")
recipientCC.Type = outlook.OlMailRecipientType.olCC
'hidden recipients section
' recipientBCC = recipients.Add("")
' recipientBCC.Type = outlook.OlMailRecipientType.olBCC
retValue = recipients.ResolveAll()
Catch ex As Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
Finally
If Not IsNothing(recipientBCC) Then Marshal.ReleaseComObject(recipientBCC)
If Not IsNothing(recipientCC) Then Marshal.ReleaseComObject(recipientCC)
If Not IsNothing(recipientTo) Then Marshal.ReleaseComObject(recipientTo)
If Not IsNothing(recipients) Then Marshal.ReleaseComObject(recipients)
End Try
Return retValue
End Function
Private Sub MailTime()
Dim OTmail As outlook.MailItem
Dim AppOutlook As New outlook.Application
Try
OTmail = AppOutlook.CreateItem(outlook.OlItemType.olMailItem)
'add users from AddRecipients
AddRecipients(OTmail)
OTmail.Subject = "Test OT mail"
OTmail.Body = "Test Ot mail"
OTmail.BodyFormat = outlook.OlBodyFormat.olFormatHTML
OTmail.Display()
Catch ex As Exception
MessageBox.Show("Could not send, resolve the errors !")
MessageBox.Show(ex.ToString)
Finally
OTmail = Nothing
AppOutlook = Nothing
End Try
End Sub
This will loop through all the TextBoxes and get a Distinct list for you.
Private Function uniqueRecipients() As List(Of String)
Dim recipients As List(Of String) = New List(Of String)
For Each ctrl As TextBox In Me.Controls.OfType(Of TextBox)
recipients.Add(ctrl.Text)
Next
Return recipients.Distinct.ToList
End Function
Private Sub Button26_Click(sender As Object, e As EventArgs) Handles Button26.Click
Try
Dim myRecips As List(Of String) = uniqueRecipients()
Dim oneLine As String = Strings.Join(myRecips.Where(Function(s) Not String.IsNullOrEmpty(s)).ToArray(), ";")
'send mail
Catch ex As Exception
MessageBox.Show(String.Concat("An error occurred: ", ex.Message))
End Try
End Sub
Use right tool type for the job - HashSet(Of String), Enumerable.ToHashSet Method
Private Function GenerateMailRecipientsFrom(textboxes As IEnumerable(Of TextBox)) As String
Dim uniqueRecipients = textboxes.
Select(Function(textbox) textbox.Text).
Where(Function(text) String.IsNullOrWhiteSpace(text) = False).
ToHashSet()
Return String.Join(";", uniqueRecipients)
End Function
HashSet accepts only unique values.
Then use a collection of all textboxes on the form
Dim mailTo As String = GenerateMailRecipientsFrom(Me.Controls.OfType(Of TextBox))
When you have predefined collection of textboxes you can still use the same method
Dim userMailTextBoxes As textBox() = { Mail_user1, Mail_user2, .. }
Dim mailTo As String = GenerateMailRecipientsFrom(userMailTextBoxes)
Nice one ! #Fabrio thanks for the code and explanation. As a side note, I have tried to load the unique values into a listbox and then insert them into outlook email while using this method:
Dim x As Long
For x = 0 To ListBox1.Items.Count - 1
If ListBox1.Items.Item(x) <> "" Then
recipientTo = recipients.Add(ListBox1.Items.Item(x))
recipientTo.Type = outlook.OlMailRecipientType.olTo
End If
Next
Worked like a charm :)

Check if ActiveX label contains part of string

I am using this code to hide a label based on if it contains % sign only and nothing else.
It is this part of the code it is erroring now when running. Error: "OLEFormat.Object: Invalid Request. Command cannot be applied to a shape range with multiple shapes"
What should be the correct code?
If InStr(1, myRange.OLEFormat.Object.Caption, "%", vbTextCompare) > 0 Then
Sub c_Three_RemovePercent()
For slideNumber = 1 To 11
Set mydocument = ActivePresentation.Slides(slideNumber)
mydocument.Select
Dim myArray() As Variant
Dim myRange As Object
myArray = Array("Lbl_V1", "Lbl_V2", "Lbl_V3", "Lbl_V4", "Lbl_V5")
Set myRange = ActivePresentation.Slides(1).Shapes.Range(myArray)
With mydocument.Shapes.Range(myArray)
If InStr(1, myRange.OLEFormat.Object.Caption, "%", vbTextCompare) > 0 Then
mydocument.Shapes(myRange).Visible = False
Else: mydocument.Shapes(myRange).Visible = True
End If
End With
Next slideNumber
End Sub
All these blindfolded late-bound member calls are easily confusing: you don't get IntelliSense to help you navigate the available members.
You're looking for an OLEObject, so declare one; assign it:
Dim oleLabel As Excel.OLEObject
Set oleLabel = ActivePresentation.Slides(1).Shapes("SomeShapeName").OLEFormat.Object
Now you want the control that's in that OLEObject's Object property, and you want to cast that control to its MSForms.Label interface:
Dim labelControl As MSForms.Label
Set labelControl = oleLabel.Object
Now you have an early-bound MSForms.Label interface to query, and IntelliSense guides you all the way:
If Contains(labelControl.Caption, "%") Then
'...
Else
'...
End If
Where Contains could look something like this:
Public Function Contains(ByVal source As String, ByVal substring As String) As Boolean
Contains = InStr(1, source, substring, vbTextCompare) > 0
End Function
You have an array of label control names you want to iterate - just iterate it:
Dim labelNames As Variant
labelNames = Array("label1", "label2", "label3", ...)
Dim i As Long
For i = LBound(labelNames) To UBound(labelNames)
Set oleLabel = currentSlide.Shapes(labelNames(i)).OLEObject
oleLabel.Visible = Not Contains(labelControl.Caption, "%")
Next
Note how this:
If BooleanExpression Then
Thing = True
Else
Thing = False
End If
Can be rewritten as:
Thing = BooleanExpression
For checking if string contains the vba function INSTR is typically best. Basically in the below example... Starting in the first position, check this text, look for "%", case insensative.
If InStr(1, myRange.OLEFormat.Object.Caption, "%", vbTextCompare) > 0 Then
mydocument.Shapes(myRange).Visible = False
Else: mydocument.Shapes(myRange).Visible = True
End If

Procedure Type Influence On Outcome: TypeName and TypeOf Behaving Differently Inside Subs and Functions

Working with Win64, VBA7 32bits on a simple combo of procedures to do things to an instance of Internet Explorer (IE instance), I've found that:
a. the function correctly identifies the IE instance type as IWebBrowser2;
b. the sub incorrectly identifies the IE instance type as String.
Would anyone gently share why?
Thanks in advance.
Sub SimpleTest()
Dim iemIE As InternetExplorer
Dim oDummy As Object
Set ieIE = New InternetExplorer
Set oDummy = mahFunction(ieIE)
mahSub (ieIE)
ieIE.Quit
End Sub
Function mahFunction(InternetExplorerThatHasMahObject As Variant) As Object
Dim sFunctionTypeName As String
Dim bFunctionTestIE As Boolean, bFunctionTestIEM As Boolean
sFunctionTypeName = TypeName(InternetExplorerThatHasMahObject) 'returns "IWebBrowser2"
bFunctionTestIE = TypeOf InternetExplorerThatHasMahObject Is InternetExplorer 'returns True
bFunctionTestIEM = TypeOf InternetExplorerThatHasMahObject Is InternetExplorerMedium 'returns True
MsgBox sFunctionTypeName & ", " & bFunctionTestIE & ", " & bFunctionTestIEM
Set mahFunction = Nothing
End Function
Sub mahSub(InternetExplorerToWaitFor As Variant)
Dim sSubTypeName As String
Dim bSubTestIE As Boolean, bSubTestIEM As Boolean
sSubTypeName = TypeName(InternetExplorerToWaitFor) 'returns "String"
bSubTestIE = TypeOf InternetExplorerToWaitFor Is InternetExplorer 'returns False
bSubTestIEM = TypeOf InternetExplorerToWaitFor Is InternetExplorerMedium 'returns False
MsgBox sSubTypeName & ", " & bSubTestIE & ", " & bSubTestIEM
End Sub

A practical example of evenly distributing n lists into a single list

I had previously asked about how to evenly distribute the items in n lists into a single list and was referred to this question: Good algorithm for combining items from N lists into one with balanced distribution?.
I made a practical example of my solution for this in VBA for Excel, since my application for this was resorting my Spotify lists which can be easily pasted into Excel for manipulation. Assumptions are that you have a headerless worksheet (wsSource) of songs with columns A, B, C representing Artist, Song, SpotifyURI respectively, a "Totals" worksheet (wsTotals) containing the sum of songs for each Artist from wsSource sorted in descending order, and a "Destination" worksheet where the new list will be created. Could I get some suggestions to improve this? I was going to get rid of the totals worksheet and have this portion done in code, but I have to go and I wanted to go ahead and put this out there. Thanks!
Sub WeaveSort()
Dim wb As Workbook
Dim wsDest As Worksheet
Dim wsSource As Worksheet
Dim wsTotals As Worksheet
Dim i As Integer
Dim iLast As Integer
Dim iDest As Integer
Dim iSource As Integer
Dim iOldRow As Integer
Dim iNewRow As Integer
Dim dDiff As Double
Dim dDiffSum As Double
Set wb = ThisWorkbook
Set wsTotals = wb.Worksheets("Totals")
Set wsSource = wb.Worksheets("Source")
Set wsDest = wb.Worksheets("Dest")
iLast = wsTotals.Range("A1").End(xlDown).Row - 1
For i = 2 To iLast
iSource = wsTotals.Range("B" & i).Value
iDest = wsDest.Range("A99999").End(xlUp).Row
If i = 2 Then
wsDest.Range("A1:C" & iSource).Value2 = wsSource.Range("A1:C" & iSource).Value2
wsSource.Range("A1:C" & iSource).Delete (xlShiftUp)
GoTo NextI
End If
dDiff = iDest / iSource
dDiffSum = 0
iNewRow = 0
For iOldRow = 1 To iSource
dDiff = iDest / iSource
dDiffSum = dDiffSum + dDiff
iNewRow = Round(dDiffSum, 0)
wsSource.Rows(iOldRow).Copy
wsDest.Rows(iNewRow).Insert xlShiftDown
iDest = iDest + 1
Next iOldRow
wsSource.Range("A1:C" & iSource).Delete (xlShiftUp)
NextI:
Next i
End Sub
Great question! I would take an object oritentated approach. Also I didn;t think it was clear what the logic was so here is my answer. Two classes and one normal module. Save these separately with the filenames ListManager.cls, List.cls, tstListManager.bas
So the ListManager.cls is this
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "ListManager"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Private mdic As Object
Public Sub Initialise(ByVal vLists As Variant)
Set mdic = VBA.CreateObject("Scripting.Dictionary")
Dim vListLoop As Variant
For Each vListLoop In vLists
Dim oList As List
Set oList = New List
oList.Initialise vListLoop, ""
mdic.Add mdic.Count, oList
Next
End Sub
Public Function WeaveSort() As Variant
Dim dicReturn As Object
Set dicReturn = VBA.CreateObject("Scripting.Dictionary")
Dim oNextList As List
Set oNextList = Me.WhichListHasLeastProgress
While oNextList.PercentageDone <= 1
Dim vListItem As Variant
vListItem = oNextList.GetListItem
dicReturn.Add dicReturn.Count, vListItem
oNextList.MoveNext
Set oNextList = Me.WhichListHasLeastProgress
Wend
Dim vItems As Variant
vItems = dicReturn.Items
'I don't like this bit
ReDim vRet(1 To dicReturn.Count, 1 To 1)
Dim lLoop As Long
For lLoop = 0 To dicReturn.Count - 1
vRet(lLoop + 1, 1) = vItems(lLoop)
Next lLoop
WeaveSort = vRet
End Function
Public Function WhichListHasLeastProgress() As List
Dim vKeyLoop As Variant
Dim oListLoop As List
Dim oLeastProgress As List
For Each vKeyLoop In mdic.keys
Set oListLoop = mdic.Item(vKeyLoop)
If oLeastProgress Is Nothing Then
'nothing to compare yet
Set oLeastProgress = oListLoop
Else
If oListLoop.PercentageDone < oLeastProgress.PercentageDone Then
'definitely take this new candidate
Set oLeastProgress = oListLoop
ElseIf oListLoop.PercentageDone = oLeastProgress.PercentageDone And oListLoop.Size > oListLoop.Size Then
'close thing, both showing equal progress but we should give it to the one with the bigger "queue"
Set oLeastProgress = oListLoop
Else
'no swap
End If
End If
Next
'return the answer
Set WhichListHasLeastProgress = oLeastProgress
End Function
and the List.cls file is
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "List"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Private mvList As Variant
Private mlCount As Long
Private mlCursor As Long
Private mvName As Variant
Public Function Initialise(ByRef vList As Variant, ByVal vName As Variant)
Debug.Assert TypeName(vList(1, 1)) <> "" ' this will break unless you specify a 2d array
Debug.Assert LBound(vList, 1) = 1 ' this ensure you got it from a sheet
mvList = vList
mlCount = UBound(mvList)
mlCursor = 1
mvName = vName
End Function
Public Function GetListItem()
GetListItem = mvList(mlCursor, 1)
End Function
Public Function Name() As Variant
Name = mvName
End Function
Public Function MoveNext() As Boolean
mlCursor = mlCursor + 1
MoveNext = (mlCursor < mlCount)
End Function
Public Function Size() As Long
Size = mlCount
End Function
Public Function PercentageDone() As Double
PercentageDone = mlCursor / mlCount
End Function
The last file is this tstListManager.bas
Attribute VB_Name = "tstListManager"
Option Explicit
Sub test()
Dim oListMan As ListManager
Set oListMan = New ListManager
Dim vLists As Variant
vLists = VBA.Array(ThisWorkbook.Sheets("Source").Range("A1:A3").Value2, _
ThisWorkbook.Sheets("Source").Range("B1:B2").Value2, _
ThisWorkbook.Sheets("Source").Range("C1:C5").Value2)
oListMan.Initialise vLists
Dim vSorted As Variant
vSorted = oListMan.WeaveSort
Dim lTotal As Long
ThisWorkbook.Sheets("Dest").Range("A1").Resize(UBound(vSorted, 1)).Value2 = vSorted
End Sub
Finally, the test data was in A1:A3 B1:B2 C1:C5
You should note I have abstracted away any Excel reading/writing logic and the pure weavesort logic is not cluttered.
Feel free to reject outright. Object orientation can be quite controversial and we think differently. :)

ArcObjects - enumerating feature classes and datasets within a geodatabase

I'm trying to enumerate the contents (feature classes and feature datasets, not interested in tables, etc) of a file geodatabase using vba/arcobjects.
I have the file GDB set as an IGxDatabase object, but can't find a way of getting further in. I've had a look at the geodatabase object model and tried using IFeatureClass and IFeatureDataset but neither seem to return useful results.
Thanks in advance for any assistance
It is much faster to enumerate the names contained in a geodatabase instead of the things that the names can open. The tricky part is looping through names in a featuredataset. While IFeatureWorkspace.Open can be used to open a featureclass without first opening the featuredataset that contains it, getting at featureclassnames within a featuredataset requires opening the featuredataset.
If you know for sure you'll need to open each featureclass, then I suppose it wouldn't hurt to use IWorkspace.Datasets, IEnumDataset, and IDataset instead of IWorkspaceDatasetNames, IEnumDatasetname and IDatasetname.
Option Explicit
Sub TestGetContents()
Dim pGxApp As IGxApplication
Set pGxApp = Application
If Not TypeOf pGxApp.SelectedObject Is IGxDatabase Then
Debug.Print "select a geodb first"
Exit Sub
End If
Dim c As Collection
Set c = GetContents(pGxApp.SelectedObject)
Dim l As Long
For l = 1 To c.Count
Dim pName As IName
Set pName = c.Item(l)
If TypeOf pName Is IFeatureClassName Then
Dim pFC As IFeatureClass
Set pFC = pName.Open
Debug.Print pFC.AliasName, pFC.FeatureCount(Nothing)
ElseIf TypeOf pName Is IFeatureDatasetName Then
Dim pDSName As IDatasetName
Set pDSName = pName
Debug.Print pDSName.name, "(featuredataset)"
End If
Next l
End Sub
Function GetContents(pGxDB As IGxDatabase) As Collection
Dim c As New Collection
Dim pEnumDSName As IEnumDatasetName
Set pEnumDSName = pGxDB.Workspace.DatasetNames(esriDTAny)
Dim pDSName As IDatasetName
Set pDSName = pEnumDSName.Next
Do Until pDSName Is Nothing
If TypeOf pDSName Is IFeatureClassName Then
c.Add pDSName
ElseIf TypeOf pDSName Is IFeatureDatasetName Then
c.Add pDSName
AddSubNames pDSName, c
End If
Set pDSName = pEnumDSName.Next
Loop
Set GetContents = c
End Function
Sub AddSubNames(pDSName1 As IDatasetName, c As Collection)
Dim pEnumDSName As IEnumDatasetName
Set pEnumDSName = pDSName1.SubsetNames
pEnumDSName.Reset
Dim pDSName2 As IDatasetName
Set pDSName2 = pEnumDSName.Next
Do Until pDSName2 Is Nothing
If TypeOf pDSName2 Is IFeatureClassName Then
c.Add pDSName2
End If
Set pDSName2 = pEnumDSName.Next
Loop
End Sub
you can use the ListFeatureClasses Method on the Geoprocessor
(the following shows how this can be done in C#)
IGeoProcessor gp = new GeoProcessorClass();
gp.SetEnvironmentValue("workspace", #"C:\temp");
IGpEnumList gpEnumList = gp.ListFeatureClasses("*", "Polygon", "");
string fc = gpEnumList.Next();
while (fc != "")
{
//Do whatever
}