Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


8580 / 13645 ツリー ←次へ | 前へ→

【32387】ユーザー定義関数で まさ 05/12/13(火) 20:31 質問[未読]
【32390】Re:ユーザー定義関数で kobasan 05/12/13(火) 21:28 回答[未読]
【32391】Re:ユーザー定義関数で ichinose 05/12/13(火) 21:43 発言[未読]
【32394】Re:ユーザー定義関数で まさ 05/12/13(火) 22:32 質問[未読]
【32401】Re:ユーザー定義関数で ichinose 05/12/14(水) 9:45 発言[未読]
【32479】Re:ユーザー定義関数で まさ 05/12/15(木) 18:39 質問[未読]
【32484】Re:ユーザー定義関数で kobasan 05/12/15(木) 21:24 発言[未読]
【32486】Re:ユーザー定義関数で ichinose 05/12/15(木) 22:27 発言[未読]

【32387】ユーザー定義関数で
質問  まさ  - 05/12/13(火) 20:31 -

引用なし
パスワード
   セルに以下のようなデーター(左3列)があり、関数で処理したいのです。

1    2    3   =関数()  →○
3    8    0     々    →×
2    10   1     々    →○
6    1    2     々    →○
−1   0    4     々    →×
0    1    8     々    →×
30   50   0   =関数()  →×

概要として、左3列で同じ行に1と2があれば関数の結果が○
そうでなければ×となるような関数を作りたいです。

【32390】Re:ユーザー定義関数で
回答  kobasan  - 05/12/13(火) 21:28 -

引用なし
パスワード
   ▼まさ さん 今晩は。

こんな感じでどうですか。

=comp(A1,B1,C1)

のようにして使ってください。

Function comp(r1 As Range, r2 As Range, r3 As Range)
  If (r1.Value - 1) * (r2.Value - 1) * (r3.Value - 1) = 0 And _
    (r1.Value - 2) * (r2.Value - 2) * (r3.Value - 2) = 0 Then
    comp = "○"
  Else
    comp = "×"
  End If
End Function


>セルに以下のようなデーター(左3列)があり、関数で処理したいのです。
>
>1    2    3   =関数()  →○
>3    8    0     々    →×
>2    10   1     々    →○
>6    1    2     々    →○
>−1   0    4     々    →×
>0    1    8     々    →×
>30   50   0   =関数()  →×
>
>概要として、左3列で同じ行に1と2があれば関数の結果が○
>そうでなければ×となるような関数を作りたいです。

【32391】Re:ユーザー定義関数で
発言  ichinose  - 05/12/13(火) 21:43 -

引用なし
パスワード
   まさ さん、kobasan さん、こんばんは。

>>
>>1    2    3   =関数()  →○
>>3    8    0     々    →×
>>2    10   1     々    →○
>>6    1    2     々    →○
>>−1   0    4     々    →×
>>0    1    8     々    →×
>>30   50   0   =関数()  →×
>>
数式でもいけそうですよ!!

「=IF(COUNTIF(A1:C1,1)*COUNTIF(A1:C1,2)>0,"○","×")」

敢えてユーザー定義関数にするなら、
'==============================================================
Function chkvalue(rng As Range, ParamArray f_value()) As Variant
'機能  : 指定されたセル範囲に指定されたデータの有無を調査する
'入力  : rng --- 調査するセル範囲
'      f_value()- 有無を調査するデータ群
'出力  : chkvalue---○--f_value()の全てのデータがセル範囲に存在する
'            ×--f_value()の中の少なくとも一つのデータがセル範囲に存在しない
'記述例 : =chkvalue(a1:c3,1,2) セル範囲A1:C1の中に1,2の両方が存在するか調査する
  Dim idx As Long
  chkvalue = "○"
  For idx = LBound(f_value()) To UBound(f_value())
   If Application.CountIf(rng, f_value(idx)) <= 0 Then
     chkvalue = "×"
     Exit For
     End If
   Next idx
End Function


「=chkvalue(a1:c1,1,2)」

確認してください

【32394】Re:ユーザー定義関数で
質問  まさ  - 05/12/13(火) 22:32 -

引用なし
パスワード
   お二方、早速のご提案ありがとうございます。
しょっぱなから細かい条件を書くと、お伝えしにくいと思い
省略した部分をさらに質問したいと思います。
直感的に関数の中が想像できるこちらの式を採用したいと
思います。

>「=chkvalue(a1:c1,1,2)」

このような形でさらに、
1と2の組み合わせで○
1と3の組み合わせで○
0と2の組み合わせで○
0と1の組み合わせで○
を1つの関数で処理できますか?
0と3や2と3の組み合わせでは×です。

ここまででも十分なのですが、もし可能であれば・・・
データは左に行くほど重みがあり、
1と2は○
2と1は×
1と3は○
3と1は△
0と2は○
2と0は△
0と1は○
1と0は△
これ以外は×
というものです。
3列ありますが、
70・1・2
1・2・70
1・70・2  これらが○

2・0・70
70・2・0  これらは△

2・70・0  は×
(△のものは隣あう列である)

Select case を使えば可能でしょうか?

【32401】Re:ユーザー定義関数で
発言  ichinose  - 05/12/14(水) 9:45 -

引用なし
パスワード
   ▼まさ さん:
おはようございます。

>お二方、早速のご提案ありがとうございます。
>しょっぱなから細かい条件を書くと、お伝えしにくいと思い
>省略した部分をさらに質問したいと思います。
これは、最初から記述してください。
だって、仕様が大きく違っていますからね!!


Chkvalueを以下のように変更しました。
'============================================================
Function chkvalue(rng As Range, ParamArray f_value()) As Variant
'機能  : 指定されたセル範囲に指定されたデータの有無を調査する
'入力  : rng --- 調査するセル範囲
'      f_value()- 有無を調査するデータ群(3の倍数分の要素が必要)
'     連続する3つ要素をパックデータとします。第一、第二要素は検索データ
'     第三要素は△判定をするか否かのフラグ 0-△判定しない 1-△判定する
'出力  : chkvalue---○--f_value()の全てのデータがセル範囲に存在する
'            △--f_value()のパックデータ第二、第一とこの純情で連続して存在した場合
'            ×--f_value()の中の検索パックデータのいずれにも属さない場合
'記述例 : =chkvalue(a1:c3,1,2,0) セル範囲A1:C1の中に1,2の両方が1,2の順序で存在するか調査する
'      =chkvalue(a1:c3,1,2,0,0,3,1)
'      セル範囲A1:C1の中に1,2の両方が1,2の順序で存在するか調査する
'      又、0,3の両方が0,3の順序で存在するか調査し、且つ、3,0で連続して存在した場合は△判定とする
  Dim idx As Long
  chkvalue = "×"
  Dim chkstr As Variant
  chkstr = ""
  For idx = 1 To rng.Count
    chkstr = chkstr & "(" & rng.Cells(idx).Value & ")"
    Next
'  MsgBox chkstr
  Dim regEx
  Set regEx = CreateObject("VBScript.RegExp")
  ' 正規表現を作成します。
  regEx.IgnoreCase = True ' 大文字と小文字を区別しないように設定します。
  regEx.Global = True  ' 文字列全体を検索するように設定します。
  For idx = LBound(f_value()) To UBound(f_value()) Step 3
    regEx.Pattern = "\(" & f_value(idx) & "\).*\(" & f_value(idx + 1) & "\).*"
'    MsgBox regEx.Pattern
    
    If regEx.test(chkstr) Then
      chkvalue = "○"
      Exit For
    Else
      If f_value(idx + 2) = 1 Then
       regEx.Pattern = "\(" & f_value(idx + 1) & "\)\(" & f_value(idx) & "\).*"
       If regEx.test(chkstr) Then
         chkvalue = "△"
         Exit For
         End If
        End If
      End If
   Next idx
  Set regEx = Nothing
End Function


1    2    3   
3    8    0   
2    10   1   
6    1    2   
−1   1    0   
0    1    8   
30   50   0

このデータがセルA1からC7に入っていた時、

1と2は○
2と1は×
1と3は○
3と1は△
0と2は○
2と0は△
0と1は○
1と0は△
これ以外は×

という条件だとすると
「=chkvalue(A1:C1,1,2,0,1,3,1,0,1,1,0,2,1)」
なんて指定してフィル操作してください。
上記のデータの判定が

×
×



×
となります。
但し、セルにあるデータには数値という想定です。
確認してみてください。

【32479】Re:ユーザー定義関数で
質問  まさ  - 05/12/15(木) 18:39 -

引用なし
パスワード
   注文が多いのにこんなに早く、的確に作成して頂き
ありがとうございます。

>これは、最初から記述してください。
>だって、仕様が大きく違っていますからね!!

申し訳ありません。
さて、設定方法でわからない部分があります。
=chkvalue(a1:c3,1,2,0,0,3,1)
で、範囲指定以降の1,2,0,0,3,1の部分です。
今後、○判定にしたい数字の組み合わせが変わった場合など
この部分の数字はどう入力すればいいでしょうか?

【32484】Re:ユーザー定義関数で
発言  kobasan  - 05/12/15(木) 21:24 -

引用なし
パスワード
   皆さん 今晩は。

質問とは別だけど、またやってみたので、分りやすかったら参考にしてください。

並びの重みを整理するのに下記の表で考えてみました。それで、
(○)(△)は×でなく表のようになるのではないかと勝手に推測して作ってみました。


        後に出る数字            
          0     1     2     3
先    0     ×     ○     ○    (○)
に    1     △     ×     ○     ○
出    2     △     △     ×    (○)
る    3    (△)    △    (△)    ×
数                    
字                    


'入力  : rng   --->調査するセル範囲
'出力  : f_compare--->○,△,×
'記述例 : =f_compare(a1:c1)

Function f_compare(rng As Range) As Variant
Dim i As Integer, j As Integer
Dim x(1 To 3) As Variant
  x(1) = rng.Cells(1).Value
  x(2) = rng.Cells(2).Value
  x(3) = rng.Cells(3).Value
  
  f_compare = "×"
  For i = 1 To 2
  For j = i + 1 To 3
    If x(i) = 0 And (x(j) = 1 Or x(j) = 2 Or x(j) = 3) Then
      f_compare = "○": Exit Function
    ElseIf x(i) = 1 And (x(j) = 2 Or x(j) = 3) Then
      f_compare = "○": Exit Function
    ElseIf x(i) = 2 And x(j) = 3 Then
      f_compare = "○": Exit Function
    '----------------------------------
    ElseIf x(i) = 1 And x(j) = 0 Then
      f_compare = "△": Exit Function
    ElseIf x(i) = 2 And (x(j) = 0 Or x(j) = 1) Then
      f_compare = "△": Exit Function
    ElseIf x(i) = 3 And (x(j) = 0 Or x(j) = 1 Or x(j) = 2) Then
      f_compare = "△": Exit Function
    End If
  Next j
  Next i
End Function


以下、やってみて一つ勉強になりました。

dim vnt
vnt=rng.Value
がユーザー関数の中で使えなくて苦労しました。
で、ichinoseさんのコードを見て
x(1) = rng.Cells(1).Value
を使うのを勉強させてもらいました。ひとつラッキーでした。

【32486】Re:ユーザー定義関数で
発言  ichinose  - 05/12/15(木) 22:27 -

引用なし
パスワード
   こんばんは。


>さて、設定方法でわからない部分があります。
>=chkvalue(a1:c3,1,2,0,0,3,1)
>で、範囲指定以降の1,2,0,0,3,1の部分です。
>今後、○判定にしたい数字の組み合わせが変わった場合など
>この部分の数字はどう入力すればいいでしょうか?
例題が少なかったですか?

セルA1:C1が

1と2は○
2と1は×
1と3は○
3と1は△
0と2は○
2と0は△
0と1は○
1と0は△
これ以外は×

の場合、
「=chkvalue(A1:C1,1,2,0,1,3,1,0,1,1,0,2,1)」
としましたが、
正確には、

「=chkvalue(A1:C1,1,2,0,1,3,1,0,2,1,0,1,1)」

ですね。

例 A1:C1が

1と2で○
2と1で△
10と5で○
それ以外は×
6と7で○
7と6で△
それ以外は×

の場合、
「=chkvalue(A1:C1,1,2,1,10,5,0,6,7,1)」

1,2,1 で 1,2の組合せのチェックで最後が1なので△判定あり

10,5,0で 10,5の組合せのチェックで最後が0なので△判定なし

6,7,1で 6,7の組合せチェックで最後が1なので△判定あり


例 A1:C1が

1と2で○
2と1で△
それ以外は×

の場合、
「=chkvalue(A1:C1,1,2,1)」


例 A1:C1が

1と2で○
それ以外は×

の場合、
「=chkvalue(A1:C1,1,2,0)」


尚、chkvalueのコードをトレースして頂ければ判ると思いますが、

×以外の判定を得られた時点で調査は中止しています。

例 A1:C1が

1と2で○
2と1で△
10と5で○
それ以外は×
6と7で○
7と6で△
それ以外は×

の場合、
「=chkvalue(A1:C1,1,2,1,10,5,0,6,7,1)」

この数式ですと、2,1の調査で△の判定がでるとそれ以降の10,5や6,7の
チェックはしていません。


というのがこのchkvalueの引数の意味です。


もし、これでは使いづらい・・・という箇所があるならば、

この関数のインターフェース(引数の種類や指定方法)を
記述してみて下さい。
(こういう事を記述するのは良い勉強になりますよ)

8580 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free