2011-09-28 30 views
0

使用電子表格工具,是否有任何方法可以獲得列的「可能」數據類型,不包括標題行(如果存在)以及合理容忍稀疏人口而不必自己做一個樣本...有沒有辦法做到這一點?不包括標題行的Excel列數據類型

因此,例如,如果我有一個excel行像

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

我希望看到

字符串,字符串,日期時間,字符串,數字

編輯

所以我最終不得不像@Tim Anderson所建議的那樣進行採樣,但我需要處理稀疏數據的情況,並且默認t o當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; 
     } 
    } 
} 

我相信這可以進一步改善,所以請隨時發佈改進,但這是我現在需要的。

回答

1

任何輔助方法,或其他API中的SpreadsheetGear存在自動返回「可能的數據類型」爲一列值的所有轉換功能概括這一點。實現這樣的事情並不會很困難,以滿足您自己的特定需求,但如果不對數據進行「抽樣」,則無法做到這一點。下面是一個非常簡單的方法,它接受要檢查的範圍和一個指示範圍是否包含標題行的布爾值。它所做的只是檢查第一行數據以確定類型;你可能需要構建一些更健壯:

你應該知道的
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時(這些包括空,錯誤,邏輯,數字,文本)。請注意,沒有DateTime。在您的示例中,這會影響「銷售日期」列中返回的值類型,因爲日期/時間實際上是作爲表示日期/時間序列號的雙精度存儲在Excel和SpreadsheetGear中的。所以這種類型的值將返回Number,而不是像DateTime。它們在單元格中顯示爲「日期」的事實僅僅是單元格的NumberFormat函數。

+0

謝謝@Tim Anderson。事實上,我最終做了類似的事情,儘管我還需要對一些行進行抽樣以處理稀疏數據。如果有人需要做類似的事情,我會編輯我的文章。 –

1

在從不使用的SpreadsheetGear,但在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 

我相信這是可能適應

的[]

+0

感謝您回覆@布魯諾,但沒有這不是我所需要的。在電子表格設備中,實際值本身(range.Value)似乎總是一個字符串,但存在該範圍的ValueType屬性,但這總是隻給出該範圍中左上角單元格的類型,即使該範圍是「 EntireColumn「,這意味着使用這種機制,我將不得不進行抽樣以獲得」可能「類型。我希望有一些輔助方法或類已經這樣做。 –

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(see this link on ozgrid

相關問題