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

如何从加密DataTable读取指定列并解决KostenArt列不存在报错?

问题根因

核心问题出在FileGenerator.ReadFromProtectedFile方法的旧版文件解析逻辑,以及异常被吞导致问题难以定位:

  • 旧格式加密文件没有带列名+类型的头行定义,但代码仍然将第一行数据当做列定义行解析,第一行第一个单元格的内容会被设为第一列的列名,自然不存在KostenArt这个预期列名
  • 旧格式分支仅按索引设置了列的数据类型,没有手动指定固定列名,和你代码中预期的列名完全不匹配
  • ConvertDataTableToListOfISAACService方法捕获ArgumentException后没有任何日志或抛出逻辑,掩盖了错误的具体上下文
修复方案

1. 修复ReadFromProtectedFile旧格式列名逻辑

在旧格式分支(ColDef.Length <=1)中,按你定义的固定列名手动赋值,修改代码如下:

If ColDef.Length > 1 Then
    myCol.DataType = Type.GetType(ColDef(1))
    myCol.ColumnName = ColDef(0) ' 新格式保留原有列名
Else
    ' 手动指定旧格式的固定列名,和MainForm定义的常量完全匹配
    Dim oldFormatColumnNames As New List(Of String) From {
        "KostenArt", "UANR", "Ueberbegriff", "Benennung", "Anzahl", "Einheit", "Einzelkosten", "Gesamtmenge", "Summencode"
    }
    If Counter < oldFormatColumnNames.Count Then
        myCol.ColumnName = oldFormatColumnNames(Counter)
    Else
        myCol.ColumnName = $"Column{Counter}" ' 多余列默认命名
    End If
    ' 原有旧格式类型赋值逻辑保留
    Select Case Counter
        Case 4, 8, 10
            myCol.DataType = GetType(Integer)
        Case 6
            myCol.DataType = GetType(Double)
        Case Else
            myCol.DataType = GetType(String)
    End Select
End If

建议将列名常量抽到公共工具类中,保证FileGenerator和MainForm的列名定义完全一致,避免后续维护不一致

2. 转换前增加列存在性校验,优化异常处理

修改ConvertDataTableToListOfISAACService方法,先判断所有必填列是否存在,避免取值报错,同时不要吞关键异常:

Private Function ConvertDataTableToListOfISAACService(dt As DataTable, lst As List(Of ISAACService)) As List(Of ISAACService)
    ' 先校验必填列是否存在
    Dim requiredColumns As New List(Of String) From {KostenArt, UANR, Ueberbegriff, Benennung, Anzahl, Einheit, Einzelkosten, Gesamtmenge, Summencode}
    For Each col In requiredColumns
        If Not dt.Columns.Contains(col) Then
            Throw New ArgumentException($"导入文件缺少必填列:{col},请检查文件格式")
        End If
    Next

    For Each row As DataRow In dt.Rows
        Dim ISAAC As New ISAACService(
            row(KostenArt).ToString, 
            row(UANR).ToString, 
            row(Ueberbegriff).ToString, 
            row(Benennung).ToString, 
            CDbl(row(Anzahl)), 
            row(Einheit).ToString, 
            CDbl(row(Einzelkosten)), 
            CInt(row(Gesamtmenge)), 
            row(Summencode).ToString
        )
        lst.Add(ISAAC)
    Next

    Return lst
End Function

3. 可选排查优化

如果修复后还有问题,可以加一行代码输出实际生成的列名,快速确认解析结果是否符合预期:

dt1 = FileGenerator.ReadFromProtectedFile(OpenFileDialog1.FileName)
' 输出所有列名到调试窗口
For Each col As DataColumn In dt1.Columns
    Debug.WriteLine($"列名:{col.ColumnName},类型:{col.DataType.Name}")
Next
dgv1.DataSource = dt1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:45:02