读取excel文件,检查格式和值是否正确

我正在做一个testing,读取一个excel文件,检查单元格的格式和值。

我需要特别检查这些事情:

  • colA有整数
  • colB的整数格式为0001,0012等等
  • 如果ColC有1,COLD应该有一个整数
  • colE应该有一个像0300这样的4位数的时钟

这里的正确方法是什么?

现在我做function检查整数如:

Int(sheet.Cells(row, col)) = sheet.Cells(row, col) 

这将检查整数值,但最好的办法检查所有其他的事情? 我听说过一个我可以使用的validation器对象。

任何人有任何关于这个问题的技巧?

此代码根据您的规则validationActiveSheet。 对于列B,我理解你的意思是,这个值实际上是文本,而不是用前导零来格式化单元格。

 Sub Validate() Dim lRow As Long Dim lNumRows As Long Dim bRowValid As Boolean Dim bSheetValid As Boolean With ActiveSheet bSheetValid = True ' initial assumption is sheet is valid lNumRows = .Cells(.Rows.Count, 1).End(xlUp).Row For lRow = 2 To lNumRows bRowValid = IsInteger(.Cells(lRow, 1).Value) bRowValid = bRowValid And IsFormatted(.Cells(lRow, 2).Value) If .Cells(lRow, 3).Value = 1 Then bRowValid = bRowValid And IsInteger(.Cells(lRow, 4).Value) End If bRowValid = bRowValid And IsTime(.Cells(lRow, 5).Value) bSheetValid = bSheetValid And bRowValid If Not bRowValid Then ' do something here if you want to flag this row End If Next lRow End With If bSheetValid Then ' copy data to historical sheet End If End Sub Function IsInteger(vValue As Variant) As Boolean If VarType(vValue) = vbDouble Then IsInteger = (Fix(vValue) = vValue) Else IsInteger = False End If End Function Function IsFormatted(vValue As Variant) As Boolean If VarType(vValue) = vbString Or VarType(vValue) = vbDouble Then IsFormatted = vValue Like "[0-9][0-9][0-9][0-9]" Else IsFormatted = False End If End Function Function IsTime(vValue As Variant) As Boolean If IsFormatted(vValue) Then IsTime = IsDate(Left$(vValue, 2) & ":" & Right$(vValue, 2)) Else IsTime = False End If End Function 

以下是您可能要考虑的一些更改:

  • For...Loop更改For...Loop Do...Loop以便在find无效数据后立即停止。 如果您不在乎知道哪些行是无效的,请这样做。
  • 如果您想查看错误,请为无效数据添加突出显示。 在If Not bRowValid...块中执行此操作。
  • Sub Validate更改为将工作表作为参数并返回boolean的函数。 IOW,将validation与将数据复制到历史数据表的代码分开。

如果你需要parsing一个外部文件,这里有一个小Perl脚本(未经testing从我的头顶上)。

 use Regexp::Common; use Test::More; #use Spreadsheet::ParseExcel; if using excel <=2003 use Spreadsheet::XLSX; my $excel = Spreadsheet::XLSX -> new ('test.xlsx'); foreach my $sheet (@{$excel -> {Worksheet}}) { printf("Sheet: %s\n", $sheet->{Name}); $sheet -> {MaxRow} ||= $sheet -> {MinRow}; foreach my $row ($sheet -> {MinRow} .. $sheet -> {MaxRow}) { $sheet -> {MaxCol} ||= $sheet -> {MinCol}; foreach my $col ($sheet -> {MinCol} .. $sheet -> {MaxCol}) { my $cell = $sheet -> {Cells} [$row] [$col]; if ($cell) { if ($col == 0){ #colA $cell =~ qr/$RE{num}{int}/ or fail "Value '$cell' in cell($row, $col) is not an int"; } if ($col == 1){ #colB int($cell) or fail "Value '$cell' in cell($row, $col) cannot be parsed to an int"; $cell =~ /\d{4}/ or fail "Value '$cell' in cell($row, $col) does not consist of 4 digits"; # must they be consecutive? } if ($col == 3){ #D my $cellC = $sheet -> {Cells} [$row] [$col - 1] if ($cellC == 1){ $cell =~ qr/$RE{num}{int}/ or fail "Value '$cell' in cell($row, $col) is not an int although ColC is 1 "; } } # one more test for colE } } } } done_testing(); 

对于colEtesting,您必须find自己的模式/正则expression式,但这不应该太困难。 为了检查perl中的时间值,请看这里: http : //metacpan.org/pod/Regexp :: Common ::time虽然我还没有使用这个模块。

另见http://metacpan.org/pod/Regexp::Common

在VBA中,您必须加载一个Microsoft正则expression式types库(它预先安装在Windows上)。 整个VBA代码将类似于我上面的伪代码,但更详细。