You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA中修改DecimalPlaces属性无效求助(默认AUTO改0/2)

问题分析与解决

你的代码中导致DecimalPlaces属性无法生效的原因有两个关键错误:

1. CreateProperty的属性类型参数错误

设置DecimalPlaces属性时,你传递了字段的数据类型ID(vrFieldDataTypeNo)作为第二个参数,但实际上这个属性的数据类型固定为整数(dbInteger,对应数值3),和字段本身的数据类型无关。错误的类型参数会导致属性创建失败或无法正确写入数据库。

2. 未重新获取已追加表的TableDef引用

当你执行db.TableDefs.Append tdf后,内存中的tdf对象和数据库中实际的表对象已经脱节,后续对这个旧tdf对象的字段属性修改不会同步到数据库中,必须重新从db.TableDefs获取最新的引用。


修正后的代码

Sub test()
    fnReports 4
End Sub

Function fnReports(vrReportNo As Long)

    Dim db As DAO.Database
    Dim rsS As DAO.Recordset
    Dim vrSQL As String
    Dim vrTableName As String
    
    'create report table
     
    Dim tdf As DAO.TableDef
    Dim fld As DAO.Field
 
    Set db = CurrentDb
    
    vrTableName = "mtMDAR" & vrReportNo
    
    vrSQL = "SELECT MDARReportFields.SortNoField, MDARReportFields.FieldName, MDARReportFields.FieldSize, FieldFormats.FieldFormat " & _
            ", MDARReportFields.FieldDecimalNo, FieldDataTypes.FieldDataTypeNo, FieldDataTypes.FieldDataType, FieldDataTypes.FieldDataTypeVBA " & _
            "FROM FieldFormats RIGHT JOIN (FieldDataTypes RIGHT JOIN MDARReportFields ON FieldDataTypes.FieldDataTypeID = MDARReportFields.FieldDataTypeID) " & _
            "ON FieldFormats.FieldFormatID = MDARReportFields.FieldFormatID WHERE MDARReportFields.ReportNo=" & vrReportNo & "  ORDER BY MDARReportFields.SortNoField"
    
    fnDeleteObjectIfExists "table", vrTableName
    Set tdf = db.CreateTableDef(vrTableName)
    
    Dim vrFieldName As String
    Dim vrFieldSize As Long
    Dim vrFieldFormat As String
    Dim vrFieldDecimalNo As Long
    Dim vrFieldDataTypeNo As Long
    Dim prp As DAO.Property
 
    Set rsS = db.OpenRecordset(vrSQL, dbOpenSnapshot)
   
    ' 第一步:创建字段并追加表到数据库
    Do Until rsS.EOF
     
        vrFieldName = rsS!FieldName
        vrFieldDataTypeNo = rsS!FieldDataTypeNo
        If vrFieldDataTypeNo = 10 Then
            vrFieldSize = rsS!FieldSize
        End If

        With tdf
            If vrFieldDataTypeNo = 10 Then
                Set fld = .CreateField(vrFieldName, vrFieldDataTypeNo, vrFieldSize)
            Else
                Set fld = .CreateField(vrFieldName, vrFieldDataTypeNo)
            End If
            .Fields.Append fld
        End With

        rsS.MoveNext
    Loop
 
    db.TableDefs.Append tdf
    ' 关键:追加后重新获取TableDef引用
    Set tdf = db.TableDefs(vrTableName)
    
    rsS.Close
    Set rsS = db.OpenRecordset(vrSQL, dbOpenSnapshot)
    
    ' 第二步:设置字段属性
    Do Until rsS.EOF
    
        vrFieldName = rsS!FieldName
        vrFieldDataTypeNo = rsS!FieldDataTypeNo
        If vrFieldDataTypeNo <> 5 And vrFieldDataTypeNo <> 10 Then
            vrFieldFormat = rsS!FieldFormat
            vrFieldDecimalNo = rsS!FieldDecimalNo
        End If
    
        With tdf
            Set fld = .Fields(vrFieldName)
         
            If vrFieldDataTypeNo <> 5 And vrFieldDataTypeNo <> 10 Then
                ' 关键:DecimalPlaces的类型固定为dbInteger(3)
                Set prp = fld.CreateProperty("DecimalPlaces", dbInteger, vrFieldDecimalNo)
                fld.Properties.Append prp
                 
                Set prp = fld.CreateProperty("Format", dbText, vrFieldFormat)
                fld.Properties.Append prp
            
            End If
  
        End With

        rsS.MoveNext
    Loop
 
    Set tdf = Nothing
    rsS.Close
    Set rsS = Nothing
    Set db = Nothing
    
End Function

关键修改点说明

  • 在db.TableDefs.Append tdf之后,添加Set tdf = db.TableDefs(vrTableName),确保后续操作的是数据库中实际存在的表对象。
  • 设置DecimalPlaces属性时,将第二个参数从vrFieldDataTypeNo改为dbInteger(或直接写3),匹配该属性的正确数据类型。

内容的提问来源于stack exchange,提问作者Nata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:16