[[20211130221147]] 『条件にあった単価を記載』(キリン) ページの最後に飛ぶ

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

 

『条件にあった単価を記載』(キリン)

お世話になっています。
Sheet1シートにある品目について、単価表の条件を当てはめ、その単価をSheet1のS列に記載したいと思っています。初めの一歩までしかできず、条件分岐について教えていただけましたら助かります。

(単価表)シート
    B C E F H I K L N O
4行目 高さ ベース単価 材質  up料金 数量  up   幅 up   果物 up料金
5行目 7 800 C   20 400未満  30 10以下 30   RINGO 5
6行目 9 780 D 20 リンゴ 5
7行目 10 760

(正しく表示されないようですので下記に記載いたします)
B列 高さ 7、9、10
C列 ベース単価 800, 780, 760
E列 材質 C,D
F列 アップ料金 20,20
H列 数量 400未満
I列 アップ料金 30
K列 幅 10以下
L列 アップ料金 30
N列 果物 RINGO, リンゴ
O列 アップ料金 5, 5

(Sheet1)シート → 記載先
    B I K N Q S
1行目 高さ  材質  数量  幅 果物 単価
2行目 7 C 100 10 リンゴ 885
3行目 9 A 500 20 780
4行目 5 D 400 5 みかん (単価表に記載のない高さは、ブランク)
 ・・
Sub tannka()

    Dim saki As Long
    Dim moto As Long

        With Worksheets("Sheet1")
            For saki = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row
                For moto = 5 To .Cells(.Rows.Count, "B").End(xlUp).Row
                    If Worksheets("単価表").Range("B" & moto).Value = Worksheets("Sheet1").Range("B" & saki).Value Then
                        Worksheets("Sheet1").Range("S" & saki).Value = Worksheets("単価表").Range("C" & moto).Value
                    ElseIf Worksheets("単価表").Range("E" & moto).Value = Worksheets("Sheet1").Range("I" & saki).Value Then
                        Worksheets("Sheet1").Range("S" & saki).Value = Worksheets("Sheet1").Range("S" & saki).Value + Worksheets("単価表").Range("F" & moto).Value

                    End If
                Next
            Next
        End With

End Sub

上記マクロは、1回目のif条件である、単価表B列とシート1B列が同じであったら、
単価表C列の値を、シート1S列に記載するは、正しくできていると思います。
が、その後の材質がCとDの場合のみ20円アップするという箇所ができず、
それ以降もよくわからない状態となっています。
また、単価表にない高さ(ここでは5)が記載されていた時は、シート1S列にはブランクであって欲しいのですが、次の条件の材質Dの20円アップが適用され、20の記載になってしまいます。

すみませんが、教えていただけましたら助かります。
よろしくお願いいたします。

< 使用 Excel:unknown、使用 OS:unknown >


 サンプルが貧弱すぎる気がします。

 1.材質がC、Dあるんですが、それは全てのケースに適用されるんですね?
 2.400未満とか、10以下とか、数値条件に文字が入っているんですが、本当にそうなっているんですね?
 3.高さが3種類あって、他の条件はそれ以下の種類数しかない前提のコードですが、それで間違いは起きないのですね?

(半平太) 2021/11/30(火) 23:40


 Sub tannka()
    Dim sakiSh As Worksheet
    Dim motoSh As Worksheet
    Dim saki As Long
    Dim moto As Long
    Dim tanka As Variant

    Set motoSh = Worksheets("単価表")
    Set sakiSh = Worksheets("Sheet1")

    For saki = 2 To sakiSh.Cells(.Rows.Count, "B").End(xlUp).Row
        For moto = 5 To motoSh.Cells(.Rows.Count, "B").End(xlUp).Row
            '変数tankaを空白にする(リセット)
            tanka = ""
            'motoShのB列とsakiShのB列が等しい場合tankaにmotoShのC列を加算
            If sakiSh.Cells(saki, "B").Value = motoSh.Cells(moto, "B").Value Then
                tanka = motoSh.Cells(moto, "C").Value
                'motoShのE列とsakiShのI列が等しい場合tankaにmotoShのF列を加算
                If sakiSh.Cells(saki, "I").Value = motoSh.Cells(moto, "E").Value Then tanka = tanka + motoSh.Cells(moto, "F").Value
                'motoShのH列とsakiShのK列が等しい場合tankaにmotoShのI列を加算
                If sakiSh.Cells(saki, "K").Value = motoSh.Cells(moto, "H").Value Then tanka = tanka + motoSh.Cells(moto, "I").Value
                'motoShのK列とsakiShのN列が等しい場合tankaにmotoShのL列を加算
                If sakiSh.Cells(saki, "N").Value = motoSh.Cells(moto, "K").Value Then tanka = tanka + motoSh.Cells(moto, "L").Value
                'motoShのN列とsakiShのQ列が等しい場合tankaにmotoShのO列を加算
                If sakiSh.Cells(saki, "Q").Value = motoSh.Cells(moto, "N").Value Then tanka = tanka + motoSh.Cells(moto, "O").Value
                Exit For
            End If
        Next
        'sakiShのS列にtankaを入力
        sakiSh.Cells(saki, "S").Value = tanka
    Next
 End Sub

「以上」「未満」等は考慮していませんがたたき台程度にはなるのではないでしょうか。
(きまぐれおじさん) 2021/12/01(水) 14:10


 >H列 数量 400未満
 >K列  幅  10以下

 そこのところは、実際に近い情報がないと解決が伸びますよ。
 (エクセルは日本語が分からないので、可能性のある表現はあらかじめ全部教えておかないとならないです)

 ホントに、その指定が各列1種類しかないなら別ですが。

(半平太) 2021/12/01(水) 14:55


 Private Function CompareSample(arg1, arg2) As Boolean
    Dim buf As Boolean
    If arg1 = arg2 Then
        buf = True
    ElseIf arg2 Like "*未満" Then
        buf = (CDbl(Left(arg2, InStrRev(arg2, "未満") - 1)) > arg1)
    ElseIf arg2 Like "*以下" Then
        buf = (CDbl(Left(arg2, InStrRev(arg2, "以下") - 1)) >= arg1)
    ElseIf arg2 Like "*以上" Then
        buf = (CDbl(Left(arg2, InStrRev(arg2, "以上") - 1)) <= arg1)
    ElseIf arg2 Like "*超" Then
        buf = (CDbl(Left(arg2, InStrRev(arg2, "超") - 1)) < arg1)
    End If
    CompareSample = buf
 End Function

たたき台にこんな関数を加えてみようと思います。

Sub tannka()

    Dim sakiSh As Worksheet
    Dim motoSh As Worksheet
    Dim saki As Long
    Dim moto As Long
    Dim tanka As Variant
    Set motoSh = Worksheets("単価表")
    Set sakiSh = Worksheets("Sheet1")
    For saki = 2 To sakiSh.Cells(Rows.Count, "B").End(xlUp).Row
        For moto = 5 To motoSh.Cells(Rows.Count, "B").End(xlUp).Row
            '変数tankaを空白にする(リセット)
            tanka = ""
            'motoShのB列とsakiShのB列が等しい場合tankaにmotoShのC列を加算
            If sakiSh.Cells(saki, "B").Value = motoSh.Cells(moto, "B").Value Then
                tanka = motoSh.Cells(moto, "C").Value
                'motoShのE列とsakiShのI列を比較し条件に合致した場合tankaにmotoShのF列を加算
                If CompareSample(sakiSh.Cells(saki, "I").Value, motoSh.Cells(moto, "E").Value) Then tanka = tanka + motoSh.Cells(moto, "F").Value
                'motoShのH列とsakiShのK列を比較し条件に合致した場合tankaにmotoShのI列を加算
                If CompareSample(sakiSh.Cells(saki, "K").Value, motoSh.Cells(moto, "H").Value) Then tanka = tanka + motoSh.Cells(moto, "I").Value
                'motoShのK列とsakiShのN列を比較し条件に合致した場合tankaにmotoShのL列を加算
                If CompareSample(sakiSh.Cells(saki, "N").Value, motoSh.Cells(moto, "K").Value) Then tanka = tanka + motoSh.Cells(moto, "L").Value
                'motoShのN列とsakiShのQ列を比較し条件に合致した場合tankaにmotoShのO列を加算
                If CompareSample(sakiSh.Cells(saki, "Q").Value, motoSh.Cells(moto, "N").Value) Then tanka = tanka + motoSh.Cells(moto, "O").Value
                Exit For
            End If
        Next
        'sakiShのS列にtankaを入力
        sakiSh.Cells(saki, "S").Value = tanka
    Next
 End Sub

「400未満」「10以下」には対応しましたが、「5mm以上」のような別の文言があるとエラーになります。

半平太さん
そうですね。質問者さんを待ちたいと思います。
(きまぐれおじさん) 2021/12/01(水) 16:13


半平太様 きまぐれおじさん様

ご回答いただき、有難うございます。
説明内容に不備があり、大変申し訳ありません。

400未満の未満という言葉は、無いです。
H5セルには、400だけ記入されています。
H4セルが、数量(未満)となります。

10以下も以下という言葉は、無いです。
K5セルには、10だけ記入されています。
K4セルは、幅(以下)となります。

N6とN7は、RINGO、リンゴの文字があったら
5円アップ料金となりますが、みかんやブランクなど、違う状態の時は、アップ料金なしとなります。

単価表は、高さの種類が最大値(最大行)となり、
材質や果物は、行数が増えることもありますが、
数量の400未満だったら30円アップですが、
例えば1000以上だったらと、さらに条件が付くことは無いです。
また、幅も同様で、条件としては、10以下だったら30円アップの条件のみとなります。

説明が不足しており、申し訳ありませんでした。
よろしくお願いいたします。
(キリン) 2021/12/01(水) 22:53


やりたいことはだいたい察しがつきました。
関数でもできそうな感じですがとりあえず作りかけのマクロをいじるとこんな感じになると思います。

 Sub tannkaX()
    Dim sakiSh As Worksheet
    Dim motoSh As Worksheet
    Dim saki As Long
    Dim moto As Variant
    Dim tanka As Variant

    Set motoSh = Worksheets("単価表")
    Set sakiSh = Worksheets("Sheet1")

    For saki = 2 To sakiSh.Cells(Rows.Count, "B").End(xlUp).Row
        '変数tankaを空白にする(リセット)
        tanka = ""
        'sakiShのB列の値をmotoShのB列から探し一致するものがあったら変数motoに代入(無かった場合はエラー文字列になる)
        moto = Application.Match(sakiSh.Cells(saki, "B").Value, motoSh.Range("B5", motoSh.Cells(Rows.Count, "B").End(xlUp)), 0)
        If IsNumeric(moto) Then
            'tankaにmotoShのC列の値を加算
            tanka = motoSh.Cells(moto + 4, "C").Value
            'sakiShのI列の値をmotoShのE列から探し一致するものがあったら変数motoに代入(無かった場合はエラー文字列になる)
            moto = Application.Match(sakiSh.Cells(saki, "I").Value, motoSh.Range("E5", motoSh.Cells(Rows.Count, "E").End(xlUp)), 0)
            If IsNumeric(moto) Then
                'tankaにmotoShのF列の値を加算
                tanka = tanka + motoSh.Cells(moto + 4, "F").Value
            End If

            'sakiShのK列の値がmotoShのH5セルの値未満の場合tankaにmotoShのI5セルの値を加算
            If sakiSh.Cells(saki, "K").Value < motoSh.Cells(5, "H").Value Then
                tanka = tanka + motoSh.Cells(5, "I").Value
            End If

            'sakiShのN列の値がmotoShのK5セルの値以下の場合tankaにmotoShのL5セルの値を加算
            If sakiSh.Cells(saki, "N").Value <= motoSh.Cells(5, "K").Value Then
                tanka = tanka + motoSh.Cells(5, "L").Value
            End If

            'sakiShのQ列の値をmotoShのN列から探し一致するものがあったら変数motoに代入(無かった場合はエラー文字列になる)
            moto = Application.Match(sakiSh.Cells(saki, "Q").Value, motoSh.Range("N5", motoSh.Cells(Rows.Count, "N").End(xlUp)), 0)
            If IsNumeric(moto) Then
                'tankaにmotoShのO列の値を加算
                tanka = tanka + motoSh.Cells(moto + 4, "O").Value
            End If
        End If
        'sakiShのS列にtankaを入力
        sakiSh.Cells(saki, "S").Value = tanka
    Next
 End Sub

(きまぐれおじさん) 2021/12/02(木) 09:29


 =IF(COUNTIF(単価表!$B$5:$B$7,$B2)>0,SUM(IFERROR(VLOOKUP($B2,単価表!$B$5:$C$7,2,FALSE),),IFERROR(VLOOKUP($I2,単価表!$E$5:$F$6,2,FALSE),),($K2<単価表!$H$5)*単価表!$I$5,($N2<=単価表!$K$5)*単価表!$L$5,IFERROR(VLOOKUP($Q2,単価表!$N$5:$O$6,2,FALSE),)),"")

関数の例です。
(きまぐれおじさん) 2021/12/02(木) 09:40


きまぐれおじさん様
ご回答いただき、有難うございます。
起動できました。
今回教えていただきましたことを、他の条件分岐でも活用できるよう考えたいと思います。
本当に有難うございました。
(キリン) 2021/12/02(木) 22:51

コメント返信:

[ 一覧(最新更新順) ]


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