2011-12-08 16 views
2

ここでは、Excelのファイルを読み、セルの形式と値を確認してテストを行っています。Excelファイルを読み込み、その形式と値が正しいことを確認してください。

私は、特にこれらの事を確認する必要があります:

  • コーラ整数
  • COLBは、0001としてフォーマット整数を持っている0012など
  • COLCは1
  • を持っている場合は冷間整数を持つべきを持っています
  • colEは0300のように4桁のクロックを持つ必要があります

ここで正しいアプローチは何ですか?

今イムのような整数をチェックするための関数を作る:

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

これは、整数値をチェックしますが、他のすべてのものをチェックするいただきました!最良の方法だろうか? 私が使用できるバリデータオブジェクトについて聞いたことがあります。

誰でもこのテーマに関わることはありますか?

+0

FOR A、D、Eデータ検証が機能するはずです(データタブ、データ検証)。データ入力付きB入力マスク用。データが最初から間違っているのを防ぎます。しかし、あなたがそれを行うことができない場合は、VBAが必要になります。 – xQbert

+0

私は入力ファイルを制御できないと言います。私はvbaでそれを読んで、フォールト、vbaの自動バリデーターを使用する方法を確認しますか? – d0lph1n

+0

編集時に新しいExcelファイルをチェックしますか(Excel内から)、既存のExcelファイルをたくさんチェックする必要がありますか?それはVBAでなければならないのですか? – knb

答えて

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 

あなたが考慮する必要がありますいくつかの変更です:あなたは、すぐに無効なデータが検出されたように停止することができるよう

  • 変更Do...LoopからFor...Loop。どの行が無効であるかを気にしない場合は、これを実行します。
  • エラーを表示する場合は、無効なデータの強調表示を追加します。これはIf Not bRowValid...ブロックで行います。
  • Sub Validateをワークシートをパラメータとし、booleanを返す関数に変更します。 IOWでは、データを履歴シートにコピーするコードからバリデーションを分離します。
+1

これは実際には先頭のゼロでフォーマットされた整数ですが、あなたの答えはすばらしく、私は自分のコードでそのほとんどを使うことができます。私の問題を見て、それを解決するあなたの時間を使用していただきありがとうございます:) – d0lph1n

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で参照してください。 VBAコード全体は上記の私の擬似コードと似ていますが、より冗長です。

+2

プロンプトされていないperlスクリプト!どのような特異な提案! –

+0

Perlを試したことはありませんが、意図したように見えます。しかし、私が望んでいたのは、私が行くのを助けるために構文と機能のいくつかが優れていたことでした。それでも、あなたはupvoteを得ます:) – d0lph1n

+0

@ jean-françois-corbett:実際には、私は2つのテンプレートを組み合わせました:外​​側のループは、Perldocの "Synopsis"セクションからSpreadsheet :: XLSXのものでした。 "if"ブロック内のテストはRegexp :: Commonのperldocから来ました。私は正規表現を書きました(これはさらに単純化することができます)。それに、私は自分の仕事のために何か類似したことをしました(perlでファイルを読み書きする)。 – knb

関連する問題