我已經編寫了有關TableDef和Field屬性的代碼。這並不難,它只是包含循環遍歷Field.Properties集合並一路做一定數量的錯誤檢查。 Property.Name,Property.Type和Property.Value產生我們需要的一切。MS Access Control Property.Type沒有意義
問題:我剛剛寫了一些代碼來爲窗體和報表控件執行相同類型的屬性枚舉。屬性名稱和值通過罰款,但.Type不正確。舉個例子:
Public Sub TestPropTypes()
Dim dbs As DAO.Database
Set dbs = CurrentDb()
Dim td As TableDef
Dim fld As DAO.Field
Set td = dbs.TableDefs("CalendarEvent_")
Set fld = td.Fields("EventDescription")
PrintObjectProps fld
Dim f As Form
Dim c As Control
DoCmd.OpenForm "fmCalendarDates", acDesign
Set f = Forms!fmCalendarDates
Set c = f.Controls("Label7")
PrintObjectProps c
End Sub
Private Sub PrintObjectProps(c As Object, Optional RecursionDepth As Integer = 0)
Dim ExistingProperty As DAO.Property
Dim PropCount As Integer
Dim GotValue As Boolean
Dim v As Variant
Debug.Print c.Name
For Each ExistingProperty In c.Properties
If PropCount > 12 Then Exit Sub
GotValue = True
On Error Resume Next
v = ExistingProperty.Value
If Err.number <> 0 Then GotValue = False
On Error GoTo 0
If GotValue Then
Debug.Print " " & ExistingProperty.Name & " " _
& GetFieldDDLTypeName(ExistingProperty.Type) & "(" & ExistingProperty.Type & ") " _
& xf.Gen.dq(CStr(ExistingProperty.Value))
End If
PropCount = PropCount + 1
Next
End Sub
Public Function GetFieldDDLTypeName(FieldType As DAO.DataTypeEnum) As String
Dim rtnStr As String
' as per: http://allenbrowne.com/ser-49.html
Select Case FieldType
Case dbBoolean: rtnStr = "YESNO"
Case dbByte: rtnStr = "BYTE"
Case dbInteger: rtnStr = "SHORT"
Case dbLong: rtnStr = "LONG"
Case dbCurrency: rtnStr = "CURRENCY"
Case dbSingle: rtnStr = "SINGLE"
Case dbDouble: rtnStr = "DOUBLE"
Case dbDate: rtnStr = "DATETIME"
Case dbBinary: rtnStr = "BINARY"
Case dbText: rtnStr = "TEXT"
Case dbLongBinary: rtnStr = "LONGBINARY"
Case dbMemo: rtnStr = "MEMO"
Case DBGuid: rtnStr = "GUID"
End Select
GetFieldDDLTypeName = rtnStr
End Function
產量:
TestPropTypes
EventDescription
Attributes LONG(4) "2"
CollatingOrder SHORT(3) "1033"
Type SHORT(3) "10"
Name MEMO(12) "EventDescription"
OrdinalPosition SHORT(3) "2"
Size LONG(4) "100"
SourceField MEMO(12) "EventDescription"
SourceTable MEMO(12) "CalendarEvent_"
DataUpdatable YESNO(1) "False"
DefaultValue MEMO(12) ""
Label7
EventProcPrefix DATETIME(8) "Label7"
Name DATETIME(8) "Label7"
ControlType BYTE(2) "100"
Caption DATETIME(8) "Description"
Visible LONGBINARY(11) "True"
Width BYTE(2) "1875"
Height BYTE(2) "285"
Top BYTE(2) "425"
Left BYTE(2) "1048"
BackStyle BYTE(2) "0"
BackColor SHORT(3) "16777215"
BorderStyle BYTE(2) "0"
OldBorderStyle BYTE(2) "0"
所以你可以看到的第一組,從在的TableDef領域,產生了一種我們所期待的結果。
第二組使用完全相同的呈現代碼來自窗體上的控件。所有MEMO屬性都以DATETIME的形式出現,所有YESNO如LONGBINARY等。它至少是一致的,我可以推斷出類型轉換並編寫轉換算法。我認爲它可能首先使用ADO值(因爲YESNO是11),但是與其他ADO值沒有一致性,並且我們也明確使用DAO對象,所以沒有任何意義。
這是不一致的,我想制定一些合理的解決方案。 有沒有人遇到過這個?
在Access 2003和2007上測試過,所以我確信它在我的Access版本中不是一個奇怪的錯誤。這是一個Access 2003格式的數據庫,所以沒有擴展類型在工作中拋出扳手。
編輯:問題解決感謝HansUp。現在我們正在檢查表/字段與表單/報表屬性是否使用不同的返回值。我提供這樣的:
Public Sub TestPropTypes1()
Dim prop As DAO.Property
Dim dbs As DAO.Database
Set dbs = CurrentDb()
DoCmd.OpenForm "fmCalendarDates", acDesign
Debug.Print "Property", "Value", "varType(.Value)", ".Type"
Debug.Print
Set prop = dbs.TableDefs("CalendarEvent_").Fields("EventDate").Properties("Name")
Debug.Print prop.Name, prop.Value, varType(prop.Value), prop.Type
Set prop = dbs.TableDefs("CalendarEvent_").Fields("EventDate").Properties("Required")
Debug.Print prop.Name, prop.Value, varType(prop.Value), prop.Type
Set prop = Forms!fmCalendarDates!Label7.Properties("Name")
Debug.Print prop.Name, prop.Value, varType(prop.Value), prop.Type
Set prop = Forms!fmCalendarDates!Label7.Properties("Visible")
Debug.Print prop.Name, prop.Value, varType(prop.Value), prop.Type
End Sub
產生
TestPropTypes1
Property Value vartype(.Value) .Type
Name EventDate 8 12
Required False 11 1
Name Label7 8 8
Visible True 11 11
這將有力地表明的TableDef字段屬性確實使用了DAO.DataTypeEnum類型,而表單屬性似乎得到VBA.VbVarType回報。 例如,該字段的Required屬性返回與VbVarType爲NULL相對應的類型,而它是YesNo的DataTypeEnum。
注prop.Type和VARTYPE(prop.Value)之間的細微差別
雖然我們可以使用VARTYPE(prop.value),這通常被認爲是不好的做法,因爲該類型可能取決於內容值(例如Null),而.Type是權威元數據。在這種系統屬性的情況下,這些值可能表現良好,並且可能沒有實際區別。
真正令人驚訝的是參考資料沒有提到這個問題。
謝謝一堆,那當然是!雖然我不同意你答案的最後部分。我測試了一下,然後用測試結果編輯問題。 –