0

スプレッドシートギアを使用して、ヘッダー行 (存在する場合) を除いて、列の「可能性の高い」データ型を取得する方法はありますか?自分でサンプルを作成することなく、まばらな母集団に適度に寛容です...すでに方法はありますか?これをする?

たとえば、次のようなExcel行があるとします

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

私は見ることを期待します

文字列、文字列、日時、文字列、数値

編集

そのため、@Tim Andersonが提案したようにサンプリングする必要がありましたが、スパースデータのケースを処理する必要があり、列の型が競合する場合はデフォルトで文字列を使用する必要がありました. (これは、列をたどるループで呼び出されます。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 が含まれます)。DateTime がないことに注意してください。あなたの例では、これは「Sale Date」列に返される値の型に影響を与えます。これは、日付/時刻が実際には Excel と SpreadsheetGear に日付/時刻のシリアル番号を表す double として格納されるためです。したがって、このタイプの値は、DateTime のようなものではなく、Number を返します。それらがセルに「日付」として表示されるという事実は、単にセルの 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 に答える