2017-02-28 10 views
1

ポストhereを利用することで、ワークシート間のセルを比較するためのVBAマクロを作成することができました。しかし、今まではA1で始まらない範囲でテストしなかった。ワークシート間のセルを比較すると、A1で範囲が開始しない

B1:X50のような範囲を指定すると、シート配列の列寸法のLBoundが1で、指定範囲の先頭の列が2(B)であるという問題が発生しました。それは、列Aから始まるかどう

'Define the range to be checked 
strRangeToCheck = Summary_ws.Range("I2").Value 

'Store the range to be checked on each sheet in an array 
varSheetA = New_Data_ws.Range(strRangeToCheck) 
varSheetB = Old_Data_ws.Range(strRangeToCheck) 

'Clear current highlighted cells on data tabs 
New_Data_ws.Cells.Interior.Color = xlNone 
Old_Data_ws.Cells.Interior.Color = xlNone 

'Initialize counter 
Counter = 0 
Counter_rng.Value = Counter 

For iRow = LBound(varSheetA, 1) To UBound(varSheetA, 1) 
    For iCol = LBound(varSheetA, 2) To UBound(varSheetA, 2) 
     On Error GoTo Err_Handler 
     If IsError(New_Data_ws.Cells(iRow, iCol).Value) Or IsError(Old_Data_ws.Cells(iRow, iCol).Value) Then 
      Counter = Counter + 1 
      Error_Flag = True 
      Call Flag_Changes 
     ElseIf varSheetA(iRow, iCol) = varSheetB(iRow, iCol) And _ 
       Len(varSheetA(iRow, iCol)) = Len(varSheetB(iRow, iCol)) Then 
       'Cells are identical and lengths match 
       'Do Nothing 
     Else 'Cells are different 
      Counter = Counter + 1 'increment counter 
      Error_Flag = False 
      Call Flag_Changes 
     End If 
    Next iCol 
Next iRow 

は私が判断するためにstrRangeToCheckを評価することができるよ:ここでは私が働いているコードの一部です。その決定に基づいて、strRangeToCheckの開始列に一致するようにシートのLBoundを手動で設定することは可能でしょうか?

+0

この行は、 'strRangeToCheck = Summary_ws.Range(" I2 ")という1つのセルであるため、問題が発生します。値'範囲は常に1つのセルか、複数のセルである可能性がありますか? – Ibo

+0

そのセルには、A1:Z100のように、ユーザーが提供する文字列が含まれています。それらが無効な範囲を指定すると、エラーがスローされます。 – kschindl

答えて

1

"最初の列に一致するようにシートのLBoundを手動で設定することは可能でしょうか"という質問に対して、答えはいいえです。 Range.Valueは、常に1の下限値の配列を返します。Excelは返された配列を作成する責任があり、VBAを使用してその動作を変更することはできません。

ソリューションは、あなたの配列に.Value年代を引く前に、中間ステップとして渡されたアドレスからRangeを作成することです:

'Store the range to be checked on each sheet in an array 
Dim newRange As Range 
Dim oldRange As Range 
Set newRange = New_Data_ws.Range(strRangeToCheck) 
Set oldRange = Old_Data_ws.Range(strRangeToCheck) 
varSheetA = newRange.Value 
varSheetB = oldRange.Value 

、代わりにループでWorksheet.Cellsを使用しての、Range.Cellsを使用しています。ワークシートのアドレス指定に変換する必要がある場合は、A1から最初ののオフセットをRangeに見つけることができます。

B1:X50のあなたの例を使用する:上記のコードでは、あなただけの単一の行(私はあなたが Call Flag_Changesでやっている見当もつかないが)上のワークシートのインデックスを使用していること

Dim example As Range 
Set example = Sheet1.Range("B1:X50") 
Debug.Print example.Columns(1).Column '<-- column 2 
Debug.Print example.Rows(1).Row   '<-- row 1 

注意

If IsError(New_Data_ws.Cells(iRow, iCol).Value) Or IsError(Old_Data_ws.Cells(iRow, iCol).Value) Then 

これはまったく必要ありません。 New_Data_ws.Cells(iRow, iCol).ValuevarSheetA(iRow, iCol)とまったく同じものです。だからあなたはそれを配列に引っ張るのですよね?

If IsError(varSheetA(iRow, iCol)) Or IsError(varSheetB(iRow, iCol)) Then 

最後に、あなたがiRowiColのための宣言を含むが、それらが宣言されている場合は、避けるためにLongにそれらを変更する必要がIntegerとしてハンガリアン記法で判断しませんでした。ただ、これでその行を置き換えますオーバーフローエラー。彼らはLongとして宣言されている場合、それは私が、これはアドバイスを実装するための最もエレガントな方法があるかどうかわからないんだけど...と

+1

ご協力いただきありがとうございます!私はそれを働かせることができました。また、私はハンガリーの記法に全く知らなかった。つまり、「iRow」と「iCol」は「Long」と定義されていましたが、命名基準に準拠するようにコードを更新します。私は更新されたコードを投稿します。 – kschindl

0

を開始するためにハンガリアン記法を使用していないに対する別の引数はまだだが、ここで働いていますコードは、コミンテルンのおかげで:私のFlag_Changesサブで

'Store the range to be checked on each sheet in an array 
Set newRange = New_Data_ws.Range(strRangeToCheck) 
Set oldRange = Old_Data_ws.Range(strRangeToCheck) 
varSheetA = newRange.Value 
varSheetB = oldRange.Value 

'Variables used to track difference between array start and given range start 
row_diff = newRange.Rows(1).Row - 1 
col_diff = newRange.Columns(1).Column - 1 

'Loop through given range 
For rngRow = newRange.Rows(1).Row To newRange.Rows.Count + row_diff 
    arrRow = rngRow - row_diff 'increment row of array being evaluated 
    For rngCol = newRange.Columns(1).Column To newRange.Columns.Count + col_diff 
     arrCol = rngCol - col_diff 'increment column of array being evaluated 
     On Error GoTo Err_Handler 
     If IsError(varSheetA(arrRow, arrCol)) Or IsError(varSheetB(arrRow, arrCol)) Then 
      Counter = Counter + 1 
      Error_Flag = True 
      Call Flag_Changes 
     ElseIf varSheetA(arrRow, arrCol) = varSheetB(arrRow, arrCol) And _ 
       Len(varSheetA(arrRow, arrCol)) = Len(varSheetB(arrRow, arrCol)) Then 
       'Cells are identical and lengths match 
       'Do Nothing 
     Else 'Cells are different 
      Counter = Counter + 1 'increment counter 
      Error_Flag = False 
      Call Flag_Changes 
     End If 
    Next rngCol 
Next rngRow 

、私は、どちらかのシート上の異なるセルを強調表示し、そのセルのアドレスを印刷し、各セルの値を印刷するようなことをやって、その差です(セルが数値の場合)。

関連する問題