[[20231115115534]] 『条件付き書式の判定』(regar) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『条件付き書式の判定』(regar)

エクセルの条件付き書式により何某かの書式が設定されているセルかどうかを、
以下のユーザー定義関数で判定したいです。
「(???)」の判定式を教えていただけないでしょうか。

 Function MySpecial(cell As Range) As Boolean
    If (???) Then
        MySpecial = True
    Else
        MySpecial = False
    End If
 End Function

◆補足
_1. 条件付き書式の「適用先のセル」かどうかではなく、「適用の結果により、何某かの書式が適用されたセル」かどうかを判定したいです
_2. 何某かの書式が適用…とは、背景色、フォント、罫線がデフォルトと異なる場合とします

やはり、書式の全ての属性を一つひとつ確認するしかないのでしょうか?

< 使用 Excel:Excel2010、使用 OS:Windows10 >


 条件付き書式と同じ判定をすればいいかと。
(tkit) 2023/11/15(水) 12:50:14

 こんな感じですか?

 Sub test()
     Dim ws1 As Worksheet, ws2 As Worksheet
     Dim fc, s$, r As Range, f$
     Dim bool As Boolean

     Set ws1 = Worksheets("Sheet1")    '対象シート
     Set ws2 = Worksheets("Sheet2")    '作業用ダミーシート

     For Each r In ws1.[B1:B2]  'テスト用の範囲
         bool = False
         For Each fc In r.FormatConditions
             f = fc.Formula1
             ws2.Range(fc.AppliesTo(1).Address).Formula = f
             ws2.Range(fc.AppliesTo(1).Address).Copy ws2.Range(r.Address)
             bool = bool Or r.Parent.Evaluate(ws2.Range(r.Address).Formula)
         Next
         Debug.Print bool      '結果出力(True:条件付き書式を満たし適用あり)
     Next
 End Sub

(xyz) 2023/11/15(水) 13:17:50


 作業用シートに書き込みをしたりする関係上、Function プロシージャにはなりにくいかも。
 どなたかがトライされているでしょう。
(xyz) 2023/11/15(水) 13:21:31

ダミーシートを作成しテスト用範囲を変えて数回試してみましたが、"FALSE"しか返ってきません。
未だコードは理解できてませんが、条件付き書式の「式」と関係あるのでしょうか?
(因みに、式を満たした場合に背景色を赤にする設定にしています)
(regar) 2023/11/15(水) 18:10:18

 ああ、そうでしたか。それは失礼。(すべてを網羅できているわけではなかったですね)
 参考までに状況を教えてください。
 (1)条件付き書式の適用範囲
 (2)条件式
 (3)条件式に出てくるセルの値
 (4)マクロでどのセル範囲を指定したのか
 を具体的に教えてください。
(xyz) 2023/11/15(水) 19:01:18

テスト用の状況です。

適用範囲;A1:J1
条件式=AND(MOD(COLUMN(),2)=0,A1=C1)
セル値;3, 9, 11, 9, 11, 13, 9, 13, 9, 9(一例)
指定範囲;[A1:J1](一例)
(regar) 2023/11/15(水) 19:54:57


 これでどうですか? 
 Sub test2()
     Dim ws1 As Worksheet, ws2 As Worksheet
     Dim fc, s$, r As Range, f$, g$
     Dim bool As Boolean

     Set ws1 = Worksheets("Sheet1")    '対象シート
     Set ws2 = Worksheets("Sheet2")    '作業用のシート
     ws1.Select
     For Each r In ws1.[A1:J1]   'テスト用の範囲
         r.Select                'ここがキモでした。
         bool = False
         For Each fc In r.FormatConditions
             f = fc.Formula1
             ws2.Range(fc.AppliesTo(1).Address).Formula = f
             ws2.Range(fc.AppliesTo(1).Address).Copy ws2.Range(r.Address)
             g = ws2.Range(r.Address).Formula
             bool = bool Or r.Parent.Evaluate(g)
         Next
         Debug.Print bool        '結果出力(True:条件付き書式を満たし適用あり)
     Next
 End Sub
 なお、Formula2プロパティを使うケース(Operator プロパティが xlBetween または xlNotBetween の場合)
 には対応していません。悪しからず。
(xyz) 2023/11/15(水) 20:45:33

 ちょっとFunctionにチャレンジ

    Sub 実験()
        Cells.Clear
        [A1:J1].Value = [{3,9,11,9,11,13,9,13,9,9}]
        [A1:J1].FormatConditions.Add(Type:=xlExpression, Formula1:="=AND(MOD(COLUMN(),2)=0,A1=C1)").Interior.Color = &HFF&
        [A2].Formula = "=MySpecial(A1)"
        [A2:J2].FillRight
        ActiveSheet.Calculate
    End Sub

    Function MySpecial(Optional ByVal c As Range) As Boolean
        Application.Volatile
        If c Is Nothing Then Set c = Application.ThisCell
        Set c = c.Item(1)
        Dim f As String
        f = FormatConditionFormula1String(c)
        If Len(f) Then MySpecial = Application.Evaluate(f)
    End Function
    Private Function FormatConditionFormula1String(Optional ByVal c As Range) As String
        If c Is Nothing Then Set c = Application.ThisCell
        Set c = c.Item(1)
        Dim f1 As Variant, i As Long, fc As FormatCondition
        For i = 1 To c.Worksheet.Cells.FormatConditions.Count
            If TypeOf c.Worksheet.Cells.FormatConditions(i) Is FormatCondition Then
                Set fc = c.Worksheet.Cells.FormatConditions(i)
                If Not Intersect(fc.AppliesTo, c) Is Nothing Then
                    f1 = Application.ConvertFormula(fc.Formula1, xlA1, xlR1C1, , GetFCFormulaAnchor(fc))
                    f1 = Replace$(f1, "COLUMN()", "COLUMN(RC)")
                    f1 = Replace$(f1, "ROW()", "ROW(RC)")
                    FormatConditionFormula1String = Application.ConvertFormula(f1, xlR1C1, xlA1, , c)
                    Exit Function
                End If
            End If
        Next
     End Function
    Private Function GetFCFormulaAnchor(fc As FormatCondition) As Range
        Dim a As Range, minR As Long, minC As Long
        With fc.AppliesTo.Item(1)
            minR = .Row: minC = .Column
        End With
        For Each a In fc.AppliesTo.Areas
            If a.Row < minR Then minR = a.Row
            If a.Column < minC Then minC = a.Column
        Next
        Set GetFCFormulaAnchor = fc.AppliesTo.Worksheet.Cells(minR, minC)
    End Function

(白茶) 2023/11/15(水) 21:09:29


to xyzさん
数回試行した結果、Debug.Printは問題なかったですが、ダミーシートへの
出力はFALSEのみでした。
このダミーシートの目的は何でしょうか?

to 白茶さん
真偽値の出力は問題なかったですが、ルール書式を背景色(赤)を止めて罫線やフォントに
変えた場合に、マクロ実行後に背景色(赤)に変更されてしまいます。

以上、本日は時間なきため結果のみで失礼します。
(regar) 2023/11/15(水) 22:36:20


「実験」を実行したら当然そうなるでしょそりゃ。

(白茶) 2023/11/16(木) 01:26:34


 何をしているんですかと言われても、コード提示していますよね。そんな難しいことしていませんが。
 条件付き書式で与える式は、
 =AND(MOD(COLUMN(),2)=0,A1=C1)ですが、
 これを、安直に、作業用シートとコピーペイストを使って、
 =AND(MOD(COLUMN(),2)=0,B1=D1)
 =AND(MOD(COLUMN(),2)=0,C1=E1)とかに変換しているだけですよ。
 そして、それをEvaluateで評価させて結果を得ています。

 まあ、そんなことするくらいなら、
 A2に =AND(MOD(COLUMN(),2)=0,A1=C1) と入れて、右にコピーするというのが正解だったでしょうか。
 今のシートを汚したくないなら、それこそ別シートで、同じことをすればよいかも。

 そもそもですが、条件付き書式の条件が満たされているか、見て分からないようなら、
 書式の指定が不適切(機能していない)ということじゃないんですかね、素朴に考えると。
 実行したいことの意図が実はよくわかっていなかった(にも拘わらず反応してしまった)と言うことですね。
(xyz) 2023/11/16(木) 12:12:42

「MySpecial」関数の意図は次のように考えています。
1_先ず条件付き書式で強調表示することにより、データ全体の特徴を直感的(視覚的)に把握したい
2_個別にその強調表示されたデータの主体?(IDや名前など)を抽出する場合にこの関数を使用したい
(抽出には条件式を使えばいいが、条件式が複数あると抽出式やマクロも複雑になりそうなので)
3_強調表示したい条件は追加で出て来そうだが、当面は背景色、フォント、罫線で対応する
(将来的には、色や太さの指定に拡張?)

書式に関するコードは未体験で、提示されたコードの理解にはしばらく時間をください。
ありがとうございました。
(VBAの用語などよくわからず書いています。うまく伝わらなかったらお許しください)
(regar) 2023/11/16(木) 19:45:20


 へぇー、
 てっきり他人が作ったワークシートの条件付き書式から手っ取り早く結果だけ取り出して
 データ抽出とかそっち方面に取り掛かる為の一過性処理に使うのかなぁとかそんな感じだろうと思ってたら、
 まさかそんな意図だったとは・・・。

 いやー、「ダメだ」と言うつもりはないのですが... ^^;

 > 1_先ず条件付き書式で強調表示することにより、データ全体の特徴を直感的(視覚的)に把握
 データを分析する立場からすればそういう気持ちになるのも分かるんですが、
 ご自身で
 > 抽出する場合
 を想定していらっしゃるし、
 ご自身で
 > 条件式が複数あると抽出式やマクロも複雑になりそう
 とも懸念されていらっしゃる。
 そして
 強調表示する為にはどうやっても「条件の数式化」が必須作業となります。
 不可避です。

 データ全体の特徴を把握する前に、分析作業全体の流れも押さえて準備しないと「損」ですよ。

 こんだけの状況が揃っていて、
 なんで「わざわざ」条件付き書式から条件式を抜き出してやらねばならないのか? って事です。
 私がお示ししたコードはその「わざわざ」の部分だけを不完全ながらもやってみたに過ぎません。

 最初っから
 > =AND(MOD(COLUMN(),2)=0,A1=C1)
 これがセルにあれば、そこを参照するだけです。
 強調表示するのにも、抽出する場合も。です。

 >強調表示したい条件は追加で出て来そう
 だったら尚更セルに条件書き出す方が簡単じゃないっすか?
 複数の条件を無理矢理1本化しなくっても、
 セルに個別に単純な条件式を配置すれば、ANDでもORでも如何様にでも組合わせられます。

 どう考えてもその方が「得」だとは思うので一応言わせて頂きました。
 まあ損得が全てという訳でもありませんが。^^;

(白茶) 2023/11/16(木) 21:02:06


 >なんで「わざわざ」条件付き書式から条件式を抜き出してやらねばならないのか?

これは、強調表示されたセルかどうかを判定するための手段を言われているのでしょうか?
仮にこれが必須であれば私の想定外であり,仰る通り「わざわざ」やる気はありません。

私のイメージは、例えば背景色がデフォルトから変化したらこれは強調表示されたセルと
判定する、というものです。
ただ、デフォルトからの変化を判断するには通常設定の書式か条件付き書式かを判別する
必要があるので、到底私の手には負えないわけですが…
(regar) 2023/11/16(木) 23:16:59


 >通常設定の書式か条件付き書式かを判別する必要がある
 そうなってくるともう、それは運用の問題ですね。

 やはり私が「とやかく云う」事では無さそうです。
 お気になさらないで下さい。

(白茶) 2023/11/16(木) 23:29:16


 >1_先ず条件付き書式で強調表示することにより、データ全体の特徴を直感的(視覚的)に把握したい

 ⇒分かります。

 >2_個別にその強調表示されたデータの主体?(IDや名前など)を抽出する場合にこの関数を使用したい
 >(抽出には条件式を使えばいいが、条件式が複数あると抽出式やマクロも複雑になりそうなので)

 ⇒1番の目的は抽出することですよね?
   当然、抽出する判定がそれぞれあるならば、それぞれ関数を作るのが当然ですよ。
   最初に申し上げた通り、条件付き書式の判定と同じもので判定する、が正確です。

   1つのセルに2つの条件付き書式が該当していたら、どうするんですか?
   貴方にとって、関数を作ることが複雑であるだけで、
   条件付き書式と同じ判定をすることは、とてもシンプルです。
   貴方がやろうとしていることは、余計複雑にしていますよ。

(tkit) 2023/11/17(金) 08:36:00


お二人のご意見、ごもっともだと思います。

[[20210325141131]] 『条件付き色付きセルのカウント方法』(ひな)
この投稿を見て>DisplayFormat<を使えば何とかできるかも…と
考えたのが質問のキッカケでした。
参照先は背景色の例ですが、フォントや罫線にも応用できないかと。
ただ、通常書式と条件付き書式の区別の課題があり、ハードル高いなーと。
(そもそもできない?)
でも、通常書式を使わないようにしたら何とかなるかも、とか…。
(因みに1つのセルに2つの条件付き書式が該当する場合は、問題なしとします)

何れにせよ簡単なコードではすまなさそうで、せっかく提案いただいても
理解できなくては運用もできないので、本件は一旦保留とさせてください。
書式に関するコード知識を増やして再チャレンジしたいと考えます。

貴重なお時間ありがとうございました。

(regar) 2023/11/17(金) 11:17:07


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.