3

次のような条件付き書式を追加しようとしていました。

=($G5<>"")でセット内部を緑にする場合は、これを $A$5:$H$25 に使用します。

これを試してみて、期待どおりにうまくいき、次にこれを次のコードでVBAコードとして適応させようとしましたが、これは機能していますが、期待どおりではありません:

With ActiveSheet.UsedRange.Offset(1)
  .FormatConditions.Delete
  'set used row range to green interior color, if "Erledigt Datum" is not empty
  With .FormatConditions.Add(Type:=xlExpression, _
                             Formula1:="=($" & cstrDefaultProgressColumn & _
                                                      .row & "<>"""")")
        .Interior.ColorIndex = 4
      End With
End With

問題は.rowデバッグ中に正しい行を提供していることですが、行を設定するための解決策によっては、追加した条件式が 1 行以上ずれているようです。そのため、フォーマットされているはずの行へのオフセットを持つ条件付きフォーマットになってしまいます。

ダイアログでは、=($G6<>"")G3またはG100310またはこのようなものです。しかし、私の望むG5ではありません。

行の設定は動的にする必要があります。これは、異なる行から始まるデータを持つことができる異なるワークシートで条件付き書式を設定するために使用されるためです。

私は自分のWith取り決めを疑っていましたが、この問題は解決しませんでした.

編集:より具体的に言うと、これはUsedRangeの問題ではなく、これと同じ問題があります:

Dim rngData As Range
Set rngData = ActiveSheet.Range("A:H") 'ActiveSheet.UsedRange.Offset(1)

rngData.FormatConditions.Delete

With rngData.FormatConditions.Add(Type:=xlExpression, _
                                  Formula1:="=($" & cstrDefaultProgressColumn & _
                                                  1 & "<>"""")")
    .Interior.ColorIndex = 4
End With

私のデータは次のようになります。

1 -> empty cells
2 -> empty cells
3 -> empty cells
4 -> TitleCols -> A;B;C;...;H
5 -> Data to TitleCols
. .
. .
. .
25

この編集されたコードを Excel 2007 で実行し、条件付きダイアログで式を検索すると、それは=($G1048571<>"")である必要が=($G1<>"")あり、すべて正常に動作します。

さらに奇妙なことに、これは、各行に条件付き書式を追加するために使用された、うまく機能するコードの編集バージョンです。しかし、行全体またはその一部をフォーマットする式を書くことが可能であることに気付きました.

編集: 追加のタスク情報

ここでは条件付き書式を使用します。これは、この関数がユーザー入力に反応するようにテーブルを設定するためです。したがって、適切に設定し、ユーザーがこの表の条件付き列のセルを編集すると、対応する行が使用されている行の範囲で緑色に変わります。

ここで、メインのヘッダー行の前に行があり、さまざまな数のデータ列があり、対象の列が変わる可能性があるため、もちろんいくつかの特定の情報を使用します.

それらを最小限に抑えるために、NamedRanges を使用して正しいオフセットを決定し、正しいDefaultProgessColumn.

GetTitleRowNamedRange または header-contents によってヘッダー行を決定するために使用されます。

With ActiveSheet.UsedRange.Offset(GetTitleRow(ActiveSheet.UsedRange) - _
                                ActiveSheet.UsedRange.Rows(1).row + 1)

Formula1 を修正しました。前に構成が適切に形成されていないことがわかったためです。

Formula1:="=(" & Cells(.row, _
           Range(strMatchCol1).Column).Address(RowAbsolute:=False) & _
           "<>"""")"

strMatchCol1- 範囲の名前です。

4

3 に答える 3

4

わかりました、笑。面倒な作業を行う前に ActiveCell を設定します...

ActiveSheet.Range("A1").Activate

Excel は、FromatCondition が追加されたときに数式を破棄している自動範囲調整を行っています。

于 2012-09-14T10:00:24.900 に答える
4

条件付き書式設定とデータ検証がこの奇妙な動作を示す理由は、それらが使用する数式が通常の計算チェーンの外にあるためです。数式でアクティブなセルを参照できるようにする必要があります。=G1=""G1を使用している場合は、循環参照を作成するため、入力できません。しかし、CF や DV では、その数式を入力できます。これらの数式は、実際の数式とは異なり、現在のセルとの関連付けが解除されます。

CF 数式を入力すると、アクティブ セルに対して常に相対的になります。CFで式を作ると

=ISBLANK($G2)

A5 の場合、Excel はそれを次のように変換します。

=ISBLANK(R[-3]C7)

それがCFに入れられると、それが適用されたセルに相対的になります。したがって、行 2 では、式は次のようになります。

=ISBLANK($G655536)

(Excel 2003 の場合)。-3 行オフセットし、スプレッドシートの一番下に折り返されます。

Application.ConvertFormula を使用して、数式を他のセルに相対的に作成できます。行 5 にいて、範囲の開始が行 2 にある場合、行 8 を基準にして数式を作成します。このようにして、R[-3] は数式を A5 に $G5 (A8 から 3 行上) として配置します。 )。

Sub test()

    Dim cstrDefaultProgressColumn As String
    Dim sFormula As String

    cstrDefaultProgressColumn = "$G"

    With ActiveSheet.UsedRange.Offset(1)
        .FormatConditions.Delete
        'set used row range to green interior color, if "Erledigt Datum" is not empty

        'Build formula
        sFormula = "=ISBLANK(" & cstrDefaultProgressColumn & .Row & ")"

        'convert to r1c1
        sFormula = Application.ConvertFormula(sFormula, xlA1, xlR1C1)

        'convert to a1 and make relative
        sFormula = Application.ConvertFormula(sFormula, xlR1C1, xlA1, , ActiveCell.Offset(ActiveCell.Row - .Cells(1).Row))

        With .FormatConditions.Add(Type:=xlExpression, _
                                 Formula1:=sFormula)

            .Interior.ColorIndex = 4
        End With

    End With

End Sub

.Cells(1)この例では列が絶対であるため、行単位でのみオフセットします。CF 数式で行と列の両方が相対的な場合は、さらにオフセットが必要です。また、これは、アクティブなセルが範囲内の最初のセルの下にある場合にのみ機能します。より汎用的にするには、アクティブセルが範囲に対してどこにあるかを判断し、適切にオフセットする必要があります。オフセットが行 1 の上にある場合は、Excel のバージョンの合計行数の一番下に近いセルを参照するようにコーディングする必要があります。

選択が少し面倒だと思ったなら、これはもっと悪いことに同意するでしょう。不必要な選択とアクティブ化は大嫌いですが、条件付き書式設定とデータ検証は、必要悪となる 2 つの場所です。

于 2012-09-14T13:35:06.413 に答える
1

簡単な例:

Sub Format_Range()

Dim oRange          As Range
Dim iRange_Rows     As Integer
Dim iCnt            As Integer


'First, create a named range manually in Excel (eg. "FORMAT_RANGE")
'In your case that would be range "$A$5:$H$25". 
'You only need to do this once, 
'through VBA you can afterwards dynamically adapt size + location at any time. 

'If you don't feel comfortable with that, you can create headers 
'and look for the headers dynamically in the sheet to retrieve 
'their position dynamically too. 

'Setting this range makes it independent
'from which sheet in the workbook is active
'No unnecessary .Activate is needed and certainly no hard coded "A1" cell. 
'(which makes it more potentially subject to bugs later on) 
Set oRange = ThisWorkbook.Names("FORMAT_RANGE").RefersToRange
iRange_Rows = oRange.Rows.Count

For iCnt = 1 To iRange_Rows
    If oRange(iCnt, 1) <> oRange(iCnt, 2) Then
        oRange(iCnt, 2).Interior.ColorIndex = 4
    End If
Next iCnt

End Sub

他の返信に対する私のコメントについて:

多くの行に対してこれを行う必要がある場合は、範囲全体をメモリ (配列) にロードし、配列内の条件を確認してから、書き込む必要があるセル (フォーマット済み) に書き込みを行う方が確実に高速です。 )。
この場合、この手法は「必要」ではないことに同意できますが、その後の多くの (あらゆるタイプの) カスタマイズに柔軟に対応でき、デバッグが容易になるため (即時/ローカル/監視ウィンドウを使用)、良い方法です。
私は Offset のファンではありませんが、本来のように機能しないとは言いません。いくつかの限られたシナリオでは、問題が発生する可能性は「小さい」と言えます。それは常に(ここではオフセット+3、そこではオフセット-3、そして再び-2など...); 書くのは簡単ですが、修正するのは地獄です。また、エンド ユーザーが変更を加えると、バグが発生することもよくあります。
私はヘッダーの使用に非常に「賛成」です (ただし、Excel のデータベース機能を減らすことにも賛成です。多くの場合、Access を回避する結果になるためです)。列1と2を使用した場合でも。ヘッダーの名前付き範囲の場所に基づいて列 nr を動的に取得する方がよいでしょう。その後、別の列が挿入されても、バグは発生しません。

最後になりましたが、誇張に聞こえるかもしれませんが、前回は、プロパティと関数を備えたクラス モジュールを使用して、各シート内の潜在的なデータのすべての取得を動的に実行し、考えられるすべてのバグのチェックといくつかの追加関数を実行しました。特定のタスクを実行します。
したがって、特定のシートから多くのタイプのデータが必要な場合は、そのクラスをインスタンス化して、定義された関数を介してアクセスできるすべてのデータを自由に使用できます。これまでのところ、誰もそれを行っていることに気づいていませんが、少し手間がかかりますが、問題はほとんどありません (同じ原則を何度も使用できます)。
これはあなたが必要としているものではないと思います。しかし、それがどのように機能するかを知らないエンドユーザーのために大きなツールを作成する必要がある日が来るかもしれません。これを覚えておくとよいでしょう。

于 2012-09-14T12:47:40.860 に答える