0

使用电子表格,有什么方法可以获取列的“可能”数据类型,不包括标题行(如果存在),并且可以合理地容忍稀疏人口,而不必自己做样本......是否已经有办法了去做这个?

所以例如,如果我有一个像

| Customers | Sales Item | Sale Date  | Contact | Quantity |
| IBM       | Keyboard   | 28-10-2011 |         | 2        |
| MS        | Mouse      | 27-09-2011 | joe     | 5        |

我希望看到

字符串、字符串、日期时间、字符串、数字

编辑

所以我最终不得不像@Tim Anderson 建议的那样进行采样,但是我需要处理稀疏数据的情况,并且当 col 中的类型冲突时默认为字符串。(这在遍历 cols 的循环中调用,我不能发布它,因为它包含一些 IP)DataValueType 只是一个本地枚举,rowcount 是要采样的行数,因为我已经在采样,所以我只是忽略第 0 行如果它是标题行。

private DataType GetDataTypeFromColRange(IRange range, int rowcount, int col)
{
    var dtlist = GetValueTypes(range, rowcount, col).Distinct();
    // If conflicting types for the col default to string.
    if (dtlist.Count() != 1)
    {
        return new DataType(DataTypeValue.String);
    }
    else
    {
        return new DataType(dtlist.First());
    }
}

private IEnumerable<DataTypeValue> GetValueTypes(IRange range, int rowcount, int col)
{
    for (int i = 1; i < rowcount; i++)
    {
        switch (range[i, col].ValueType)
        {
            case SpreadsheetGear.ValueType.Text:
                yield return DataTypeValue.String;
                break;
            case SpreadsheetGear.ValueType.Number:
                if (range[i, col].NumberFormatType == NumberFormatType.Date || range[i, col].NumberFormatType ==  NumberFormatType.DateTime)
                {
                    yield return DataTypeValue.Date;
                }
                else
                {
                    yield return DataTypeValue.Numeric;
                }
                break;
            case SpreadsheetGear.ValueType.Logical:
                yield return DataTypeValue.Bool;
                break;
            default: // ignore empty or errored cells.
                continue;
        }
    }
}

我相信这可以进一步改进,所以请随时发布改进,但这正是我现在需要的。

4

3 回答 3

1

从不使用电子表格,但在 Excel 中我使用这个 UDF

Function GetType(rg As Range) As String

If IsNumeric(rg.Value) Then
    GetType = "Numeric"
ElseIf IsDate(rg.Value) Then
    GetType = "Date Time"
Else
    GetType = "String"
End If

End Function

我相信可以适应

[]的

于 2011-09-29T00:40:53.467 回答
1

SpreadsheetGear 中不存在帮助方法或其他 API 来自动返回一列值的“可能的数据类型”。实现这样的东西来满足您自己的特定要求并不是很困难,尽管没有“采样”数据就无法做到这一点。下面是一个非常简单的方法,它接受要检查的范围和一个指示范围是否包含标题行的布尔值。它所做的只是检查第一行数据以确定类型;您可能想要构建一些更强大的东西:

private SpreadsheetGear.ValueType[] GetColumnTypes(IRange range, bool hasHeader)
{
    SpreadsheetGear.ValueType[] columnTypes = new SpreadsheetGear.ValueType[range.ColumnCount];
    for (int i = 0; i < range.ColumnCount; i++)
    {
        columnTypes[i] = range[hasHeader ? 1 : 0, i].ValueType;
    }
    return columnTypes;
}

但是,您应该注意的一件事是,SpreadsheetGear 使用与 Excel 相同的基本内部数据类型,并且在检查 IRange.ValueType 时将返回这些类型(这些类型包括 Empty、Error、Logical、Number、Text)。注意没有日期时间。在您的示例中,这将影响“销售日期”列上返回的值类型,因为日期/时间实际上存储在 Excel 和 SpreadsheetGear 中,作为表示日期/时间序列号的双精度数。所以这种类型的值会返回 Number,而不是 DateTime。它们在单元格中显示为“日期”这一事实只是单元格 NumberFormat 的一个函数。

于 2011-09-29T20:50:20.300 回答
0

这是另一个基于错误处理程序和 VBA 类型转换的尝试:

Function probableType(vInput As Variant)
Dim vResult As Variant

'set error handler to resume (the procedure will check the error number)
On Error Resume Next

'check if it is an integer
vResult = CInt(vInput)
If Err.Number = 0 Then
    probableType = "Integer"
    Exit Function
End If
Err.Clear

'check if it is a date
vResult = CDate(vInput)
If Err.Number = 0 Then
    probableType = "Date"
    Exit Function
End If
Err.Clear

'else this is probably a string
probableType = "String"
End Function

可以用这个子测试:

Sub uniTest()
MsgBox probableType("12/12/12")
MsgBox probableType("12")
MsgBox probableType("myTest")
End Sub

您可以使用 Excel VBA 的所有转换函数来概括这一点(请参阅 ozgrid 上的此链接

于 2011-09-29T09:35:19.973 回答