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

时间:2011-12-08 12:07:45

标签: excel vba excel-2007

我在这里做一个关于读取excel文件的测试,检查单元格的格式和值。

我需要具体检查这些事情:

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

这里有正确的方法吗?

现在我正在制作检查整数的函数,如:

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

这将检查整数值,但是检查所有其他内容的最佳方法是什么? 我听说过我可以使用的验证器对象。

有人对这个问题有什么窍门吗?

2 个答案:

答案 0 :(得分:4)

此代码根据您的规则验证ActiveSheet。对于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更改为Do...Loop,以便在找到无效数据后立即停止。如果您不在乎知道哪些行无效,请执行此操作。
  • 如果要查看错误,请为无效数据添加突出显示。在If Not bRowValid...块中执行此操作。
  • Sub Validate更改为将工作表作为参数并返回boolean的函数。 IOW,将验证与将数据复制到历史表的代码分开。

答案 1 :(得分:3)

如果你需要解析一个外部文件,这里有一个小的perl脚本(从我头顶未经测试)。

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();

对于colE测试,你必须找到自己的模式/正则表达式,但这不应该太困难。 要检查perl中的时间值,请参见此处: http://metacpan.org/pod/Regexp::Common::time 不过,我没有使用过这个模块。

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

在VBA中,您必须加载Microsoft正则表达式类型库(预先安装在Windows上)。整个VBA代码与上面的伪代码类似,但更详细。