问题
I'm stuck trying to create a UserForm in VBA with a combobox that lists all possible TableFields(?).
Updated code: Using the code provided by @dbmitch and some freestyle. This lists a two-column combobox with both the Original and the Custom field name (if it exists). It only lists the fields used in the Activeproject. Not all possible fields. But if the field isn't used in the Activeproject anyway... maybe this is for the best!
Public strResult2 As String ' Used for custom field names
Private Sub UserForm_Initialize()
Dim objProject As MSProject.Project
Dim tskTable As MSProject.Table
Dim tskTables As MSProject.Tables
Dim tskTableField As MSProject.TableField
Dim strFieldName As String
'ComboBoxColA.ListWidth = "180" 'Uncomment for wider dropdown list, without wider box
Set objProject = Application.ActiveProject
Set tskTables = objProject.TaskTables
With ComboBox1 'Adds one blank line at the top
.ColumnCount = 2
.AddItem ""
.Column(1, 0) = "BLANK"
End With
' Loop through all tables
For Each tskTable In tskTables
' Loop through each field in each table
For Each tskTableField In tskTable.TableFields
strFieldName = GetFieldName(tskTableField)
If Len(strFieldName) = 0 Then GoTo SKIPHERE
With ComboBox1
.Value = strFieldName
' Check if allready exists
If .ListIndex = -1 Then
' Then sort alphabetically
For x = 0 To .ListCount - 1
.ListIndex = x
If strFieldName < .Value Then
.AddItem strFieldName, x
.Column(1, x) = strResult2
GoTo SKIPHERE
End If
Next x
.AddItem strFieldName
End If
End With
SKIPHERE:
Next
Next
Set objProject = Nothing
Set tskTable = Nothing
Set tskTables = Nothing
Set tskTableField = Nothing
End Sub
Function
Private Function GetFieldName(ByVal objField As MSProject.TableField) As String
' find the field name and column header for a field (column) in a data table
'strResult is placed in column 0 in ComboBox
'strResult2 is placed in column 1 in ComboBox
Dim lngFieldID As Long
Dim strResult As String
lngFieldID = objField.Field
With objField.Application
strResult = Trim(.FieldConstantToFieldName(lngFieldID))
On Error GoTo ErrorIfMinus1 ' CustomField does not handle lngFieldID= -1
If Len(Trim(CustomFieldGetName(lngFieldID))) > 0 Then strResult2 = " (" & Trim(CustomFieldGetName(lngFieldID)) & ")" Else strResult2 = ""
End With
GetFieldName = strResult
Exit Function
ErrorIfMinus1:
strResult2 = ""
Resume Next
End Function
@dbmitch helped me on my way getting this code to work. Thanks!
回答1:
That link is useful in that it shows the properties and methods available to you via the MS Project object model. You should be able to modify it to VBA format by changing it slightly.
What would have been more useful was to show your code you mentioned in...
I have found code that let me list all fields in the current table
In any case, see if this code does what you want as described in your question
Sub LoadFieldNames()
Dim objProject As MSProject.Project
Dim tskTable AS MSProject.Table
Dim tskTables AS MSProject.Tables
Dim tskTableField AS MSProject.TableField
Dim strFieldName AS String
Set objProject = Application.ActiveProject
Set tskTables = objProject.TaskTables
' Loop thru all tables
For Each tskTable In tskTables
' Loop through each field in each table
For Each tskTableField in tskTable.TableFields
strFieldName = GetFieldName(tskTableField)
ComboBox1.AddItem strFieldName
Next
Next
Set objProject = Nothing
Set tskTable = Nothing
Set tskTables = Nothing
Set tskTableField = Nothing
End Sub
Try adding the function from this post to create the function GetFieldName
... and it should compile
Private Function GetFieldName(ByVal objField As MSProject.TableField) As String
' find the field name (actually colmn heading) for a field (column) in a data table
Dim lngFieldID As Long
Dim strResult As String
lngFieldID = objField.Field
With objField.Application
strResult = Trim(objField.Title) ' first choice is to use the title specified for the column in the table
If Len(strResult) = 0 Then
' try to get the custom field name- this will come back blank if it's not a custom field
strResult = Trim((CustomFieldGetName(lngFieldID)))
End If
If Len(strResult) = 0 Then
strResult = Trim(.FieldConstantToFieldName(lngFieldID)) ' use the field name
End If
End With
GetFieldName = strResult
End Function
来源:https://stackoverflow.com/questions/51144134/loop-through-all-tablefields-in-microsoft-project-add-to-combobox