0

VBA for Excelを始めたばかりです。私は 10 年近く前に大学で VB と Java を使用し、そのときは十分に使いこなせましたが、基本的には最初からやり直しています。(ええと、自転車に乗るのは好きではありません。)

A1:J34 などとして宣言されているだけでなく、範囲を構築する方法を理解しようとしています。私のグーグルは、「範囲」と私が探しているものを示す用語を検索すると、必要なものよりもはるかに高度なヒットの雪崩が発生するという点で挑戦されています。ほとんどのヒットは、必要な基本的な要約情報にも対応していません。

だから、これがその基本です:Mac上のExcel 2011。このシートには、A から M まで、1309 までのデータがあります。これは、見出し行とそれに続くデータ行の繰り返しパターンです。うーん。シートを作成した人は、データの構成よりもシートからの印刷について考えていたようです。ピボットテーブルで使用するには、それをクリーンアップする必要があり、さらに 3 つの同様のものが必要ですが、このばかげた繰り返しレイアウトでは役に立ちません。

見出し行は次のとおりです: 姓、名、10 個の日付セル。見出しの下のデータ行はもちろん名前であり、出席を表す 1 または 0 です。各見出しの下に 20 から 30 の名前があります。それが繰り返されます。そして、日付は数セットごとに変わり、最後のセットが中断されたところから始まります.

私が今しなければならないこと: 特定の値 (列 A) で始まるすべての行を追加して、範囲を範囲変数にアセンブルしようとしています。私の場合、その値は文字列「Last Name」であるため、「Last Name」で始まるすべての行のすべてのセルを保持する範囲変数を持つことができます。これにより、日付形式にする必要があるすべてのセルがキャプチャされます。(私はそれを行っているので、日付の見出しがすべて実際に日付形式であることを確認できます-現在はすべてが日付形式ではないため、多くは単なる「一般」セルです。)

私の質問:

  1. 範囲オブジェクトに範囲ISを伝えるとき、コードを書いている人が入力した開始セルと終了セルによって定義されたブロックではなく、行基準に基づいたセル/行/列をどのようにフィードしますか? 例: A の「First Name」の存在に基づいて、列 A から I までの行 1、34、70、93、および 128 を含む範囲を作成します。
  2. これを行うための最も一般的な方法は何ですか?
  3. これらのうち、私のニーズに最も適しているのはどれですか?その理由は?
4

2 に答える 2

1

Unionこのように演算子を使用できます

Dim r As Range

Set r = Range("A1, A3, A10:A12")

またはこれ

Set r = Union(Range("A1"), Range("A3"), Range("A10:A12"))

この範囲を次のように繰り返すことができます

Dim cl as Range
For Each cl in r.Cells
    ' code cell cl
Next

またはこれ

Dim ar as Range
For each ar in r.Areas
    ' code using contiguous range ar
    For each cl in ar.Cells
        ' code using cell cl
    Next
Next
于 2013-07-20T10:47:34.653 に答える
1

これは、「Last Name」行を見つけ、それらすべての行を含む範囲オブジェクトを構築し、そのオブジェクトを反復処理して日付以外の値を検索する方法を示す実際の例です。データ範囲をバリアントの配列に読み取り、その配列で姓の行とそれらの行内の「不適切な日付」の両方を検索することで、コードを大幅に高速化できます。これは、チェックする行数が非常に多い場合に特に当てはまります。

Sub DisjointRng()

    Dim checkCol As String, checkPattern As String
    Dim dateCols()
    Dim lastCell As Range, usedRng As Range, checkRng As Range
    Dim cell As Variant
    Dim usedRow As Range, resultRng As Range, rngArea As Range
    Dim i As Long, j As Long

    checkCol = "A"             'column to check for "Last Name"
    checkPattern = "Last*"
    dateCols = Array(3, 5)     'columns to check for date formatting

    With Worksheets("Sheet1")
        'find the bottom right corner of data range; we determine the used range
            'ourselves since the built-in UsedRange is sometimes out-of-synch
        Set lastCell = .Cells(.Cells.Find(What:="*", SearchOrder:=xlRows, _
            SearchDirection:=xlPrevious, LookIn:=xlFormulas).Row, _
            .Cells.Find(What:="*", SearchOrder:=xlByColumns, _
            SearchDirection:=xlPrevious, LookIn:=xlFormulas).Column)
        Set usedRng = .Range("A1:" & lastCell.Address)
        'the column of values in which to look for "Last Name"
        Set checkRng = .Range(checkCol & "1:" & checkCol & usedRng.Rows.Count)
    End With
    'step down the column of values to check for last name & add
        'add found rows to range object
    For Each cell In checkRng
        If cell.Value Like checkPattern Then
           'create a range object for the row
            Set usedRow = Intersect(cell.EntireRow, usedRng)
            If resultRng Is Nothing Then
                'set the first row with "Last Name"
                Set resultRng = usedRow
            Else
                'add each additional found row to the result range object
                Set resultRng = Union(resultRng, usedRow)
            End If
        End If
    Next cell
    For Each rngArea In resultRng.Areas
        'if found rows are continguous, Excel consolidates them
            'into single area, so need to loop through each of the rows in area
        For i = 1 To rngArea.Rows.Count
            For j = LBound(dateCols) To UBound(dateCols)
                If Not IsDate(rngArea.Cells(i, dateCols(j))) Then
                    'do something
                End If
            Next j
        Next i
    Next rngArea
End Sub
于 2013-07-23T17:48:30.797 に答える