2013-04-12 125 views
1

我想驗證用戶選擇的範圍內的所有單元格的數據類型是相同的,使用VBA函數。我有以下代碼(簡化的),其適用於在大多數情況下:檢查範圍內的數據類型

Dim vTempRange As Variant 
Dim vCell As Variant 

    vTempRange = DataRange.Value 

    For Each vCell In vTempRange 
     If Len(vCell) > 0 Then 
      'Use TypeName(vCell) 
      'Complete validation here 
     End If 
    Next vCell 

有時,用戶可以選擇百分比的列,有時十進制值的列,有時時間值(不與相關聯的日期)。 VBA似乎將所有這三個看作是Double,這在技術上並不正確。問題是,選擇的格式將被用作最終輸出的一部分,因此12:00:00應顯示爲此,而不是0.50,這是目前的情況。

我看着結合使用是這樣的:

Dim vCell As Variant 

    For Each vCell In DataRange 
     If Len(vCell) > 0 Then 
      'Use vCell.NumberFormat 
      'Complete validation here 
     End If 
    Next vCell 

NumberFormat是不相符的。例如,用戶可能具有列爲0%0.000%h:m:shh:mm:ss的時間百分比,所以我認爲它很難正確捕獲該值。

有沒有一種方法可以在沒有用戶干預的情況下精確確定當選擇時間與其他類型之一時?確定百分比值與0<x<1十進制值也會很好,但不是必需的。

我有其他選擇可供我處理,例如忽略最終輸出中的格式(真的不可取)或明確要求用戶確定類型(但這不像我想要的那樣乾淨和不自動)。

+0

你有沒有考慮過使用正則表達式解析單元格的文本,然後根據結果強制特定的格式? –

+0

@RossMcConeghy我沒有;我覺得應該有一個更簡單的VBA解決方案。 – Gaffi

回答

3

試試這個。將其粘貼到模塊中。然後,您可以將其用作工作表公式。

我在我的數據庫中找到了這個代碼,它是從here中挑選出來的,我修改了它以滿足您的需求。

Public Function CellType(c) 
    Application.Volatile 
    Select Case True 
     Case IsEmpty(c): CellType = "Blank" 
     Case Application.IsText(c): CellType = "Text" 
     Case Application.IsLogical(c): CellType = "Logical" 
     Case Application.IsErr(c): CellType = "Error" 
     Case IsDate(c): CellType = "Date" 
     Case InStr(1, c.Text, ":") <> 0: CellType = "Time" 
     Case InStr(1, c.Text, "%") <> 0: CellType = "Percentage" 
     Case IsNumeric(c): CellType = "Value" 
    End Select 
End Function 

截圖

enter image description here

您可以進一步修改它裏面添加Case IsNumeric(c): CellType = "Value"IF子句來檢查小數,科學記數法等使用INSTR

+0

這可能已經成功了。我需要確保我的所有案件都被覆蓋,首先,但是,謝謝! – Gaffi

+0

不僅覆蓋病例很重要,但要確保它們處於特定的順序。例如,不要檢查'Case IsNumeric(c):CellType =「Number」'在檢查日期/時間/%之前,否則你將得到'number'; –

+0

對!我實際上將它鏈接到一個'Enum',所以你所列出的某些類型不被使用。我仍然會保留他們,因爲你已經說過,但是對於這些情況,我在這些情況下爲列表添加了一個「無效」項。 – Gaffi

1

申報vCell as Range,然後做你的檢查:

TypeName(vCell.Value)

這將準確地抓住你的日期。

您可能需要添加一些if/then邏輯來捕獲「百分比」,因爲它們是雙重類型值 - 「%」部分僅僅是單元格格式,因此您可能只需檢查Right(vCell.NumberFormat,1) = "%"