[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『同じ会社の直前のデータを取得するには』(どらきち)
いつも「エクセルの学校」で勉強させていただきありがとうございます。
下記のような表がありまして、同じ会社の直前のデータを取得するマクロを
作りたいのですがどうしたらよろしいかどなたかご指導をお願いします。
下表で B6 のセルに直前のX社のD列のデータ 5000 を取得するにはです。
(1行目のX社のデータはありません)
A B C D
1 X社 1000 200 2000
2 Y社 2500 300 3500
3 Z社 3000 400 3000
4 X社 2000 500 5000
5 Y社 3500 600 1400
6 X社
よろしくお願いします。
6 X社
数式でも出来ますけどマクロでしょうか。 数式の場合 A B C D 1 X社 1,000 200 2,000 2 Y社 2,500 300 3,500 3 Z社 3,000 400 3,000 4 X社 2,000 500 5,000 5 Y社 3,500 600 1,400 6 X社 5,000 B6=IF(ISNA(MATCH(A6,A1:A5,0)),"該当なし",INDEX(A1:D5,MAX((A1:A5=A6)*ROW(A1:A5)),4)) として、Shift+Ctrlキー押しながらEnterキーで確定して配列数式に。
マクロならベタベタな方法ですが、以下のような感じでしょうか。 Sub Test() For Each c In Range("A1:A5") If c.Value = Range("A6") Then MyRow = c.Row If MyRow < c.Row Then MyRow = c.Row Else MyRow = MyRow End If End If Next c If IsEmpty(MyRow) Then MsgBox ("該当する社名がありません。") Else Range("B6").Value = Cells(MyRow, 4).Value End If End Sub
※ついでに、チェンジイベントの場合です。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address <> Range("A6").Address Then Exit Sub Application.EnableEvents = False For Each c In Range("A1:A5") If c.Value = Range("A6") Then MyRow = c.Row If MyRow < c.Row Then MyRow = c.Row Else MyRow = MyRow End If End If Next c If IsEmpty(MyRow) Then MsgBox ("該当する社名がありません。") Else Range("B6").Value = Cells(MyRow, 4).Value End If Application.EnableEvents = True End Sub
(川野鮎太郎)
(*'ω'*)......ん? いくつか疑問点(^_^A; (1)>A列に社名が入ったらB列に表示したいので、マクロで良かったです ↑数式でもA列に社名を入れたらB列に値が出ますが(^_^A;
(2)>B6のセルに上段にないH社を入れて実行しますと実行時エラー ’13’ ↑入れるのはA列ですよね。 A6にH社を入れたら”該当する社名がありません。”って出ますけど(^_^A;
>>ついでに、チェンジイベントの場合です。>はどのような時にしようするのですか? シートタブを右クリックして、コードの表示をクリック VBEの画面が出るので、そこにコードをコピペです。 ※ただしA6セル限定でやってますので、実際のレイアウトに合わせてコードを書き換える必要があります。 (川野鮎太郎)
Sub TEST()
Dim n As Integer n = Range("A10000").End(xlUp).Row Dim C, MyRow As String For Each C In Range(Cells(2, 1), Cells(n - 1, 1)) If C.Value = Cells(n, 1) Then MyRow = C.Row If MyRow < C.Row Then MyRow = C.Row Else MyRow = MyRow End If End If Next C If IsEmpty(MyRow) Then MsgBox ("該当する社名がありません。") Else Cells(n, 2).Value = Cells(MyRow, 4).Value End If End Sub
配列数式は、1セルには対応できますが、次のように空白の場合の
=IF(A6="","",IF(ISNA(MATCH(A6,$A$1:A5,0)),"該当なし",INDEX($A$1:D5,MAX(($A$1:A5=A6)*ROW($A$1:A5)),4)))
配列数式がつくれない(これでは間違いですものね)ので、マクロでと思います。
上記のマクロどこがいけないでしょうか再度お願いします。
(どらきち)
MyRowがEmptyじゃないからです。実際に何なのかはステップ実行で確認してください。 (wizik)
ちょっと時間が出来たので作ってみました。 よかったら参考にして下さい。v(=∩_∩=)v (SoulMan) 最初はFindを使った場合です。シートモジュールに記述します。 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) Dim C As Range Dim MyRow As Range Dim MyTbl As Range Dim FstAdd As String If Target.Column <> 1 Then Exit Sub If Target.Row < 2 Then Exit Sub If Target.Count > 1 Then Exit Sub If IsEmpty(Target.Value) Then Exit Sub With Me If Target.Row <> .Range("A65536").End(xlUp).Row Then Exit Sub Set MyTbl = .Range("A1", .Range("A65536").End(xlUp).Offset(-1)) End With Application.EnableEvents = False Set C = MyTbl.Find(What:=Target.Value, LookIn:=xlValues, LookAt:=xlWhole, _ SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=True) If Not C Is Nothing Then FstAdd = C.Address If Not IsEmpty(C.Offset(, 3).Value) Then Target.Offset(, 1).Value = C.Offset(, 3).Value Else Do Set C = MyTbl.FindPrevious(C) If Not IsEmpty(C.Offset(, 3).Value) Then Target.Offset(, 1).Value = C.Offset(, 3).Value Exit Do End If Loop While C.Address <> FstAdd If C.Address = FstAdd Then MsgBox "対象となる数値がありません。" Target.Offset(, 1).Value = Empty End If End If Else MsgBox Target.Value & "は、ありません。" End If Application.EnableEvents = True Set MyTbl = Nothing End Sub 次は配列を使って処理する場合です。 標準モジュールに記述します。 Option Explicit Sub てすと() Dim MyA As Variant, MyB As Double Dim i As Long Dim MyFlag As Boolean Dim MyTbl As Range, MyTblA As Range With Worksheets("Sheet1") Set MyTblA = .Range("A65536").End(xlUp) Set MyTbl = .Range("A1", MyTblA) MyA = MyTbl.Resize(, 4).Value MyFlag = False For i = UBound(MyA, 1) - 1 To LBound(MyA, 1) Step -1 If MyA(UBound(MyA, 1), 1) = MyA(i, 1) Then MyFlag = True If Not IsEmpty(MyA(i, 4)) Then MyB = MyA(i, 4) Exit For End If End If Next If MyFlag = False Then MsgBox MyA(UBound(MyA, 1), 1) & "は、ありません。" Else If MyB = 0 Then MsgBox "対象となる数値がありません。" MyTblA.Offset(, 1).Value = Empty Else MyTblA.Offset(, 1).Value = MyB End If End If End With Erase MyA Set MyTbl = Nothing Set MyTblA = Nothing End Sub 最後にFor Eachを使った場合です。 これも標準モジュールに記述します。 Sub TEST() Dim C As Range, MyRow As Long Dim MyTbl As Range Dim MyKey As String Dim MyFlag As Boolean With Sheet1 Set MyTbl = .Range("A65536").End(xlUp) MyKey = MyTbl.Value For Each C In .Range("A1", MyTbl.Offset(-1)) If C.Value = MyKey Then MyFlag = True If Not IsEmpty(C.Offset(, 3)) Then MyRow = C.Row End If End If Next C If MyRow > 0 Then MyTbl.Offset(, 1).Value = .Cells(MyRow, 4).Value Else If MyFlag = False Then MsgBox MyKey & "は、ありません。" Else MsgBox "対象となる数値がありません。" End If End If End With Set MyTbl = Nothing End Sub
エラーの原因はwizikさんのご指摘のように、MyRowがEmptyじゃないからですね。
これは私の責任で、変数を定義してなかったからEmptyで良かったんですが、 ちゃんと、Dim MyRow As Longで定義すればエラーになりますね。 これならOKみたいです。 失礼しました。 Sub TEST() Dim n As Integer Dim C As Range Dim MyRow As Long n = Range("A10000").End(xlUp).Row For Each C In Range(Cells(2, 1), Cells(n - 1, 1)) If C.Value = Cells(n, 1) Then MyRow = C.Row If MyRow < C.Row Then MyRow = C.Row Else MyRow = MyRow End If End If Next C If MyRow = 0 Then MsgBox ("該当する社名がありません。") Else Cells(n, 2).Value = Cells(MyRow, 4).Value End If End Sub
ただ、行が多いと処理が遅いので、下から順番にFor NextでStep -1とした方が 早いかもしれません。
って、ここまで書いてManちゃんのを[壁]_・)チラッっと見たら、2番目がそうなってるのかな・・・。 (川野鮎太郎)
ワークシート関数のMatch関数を使ってみました。 Sub TEST() Dim n As Long, i As Long n = Range("A10000").End(xlUp).Row On Error GoTo ErrorHandler If Application.WorksheetFunction.Match(Cells(n, 1).Value, Range("A1:A" & n - 1), 0) Then For i = n - 1 To 1 Step -1 If Cells(n, 1).Value = Cells(i, 1).Value Then Cells(n, 2).Value = Cells(i, 4).Value Exit Sub End If Next i Else ErrorHandler: MsgBox ("該当する社名がありません。") End If End Sub
※これは最初に提示した計算式をマクロにしたようなものです(^_^A;
(川野鮎太郎)
(wizik) さんご指摘ありがとうございました。 (SoulMan)さん、川野さん貴重な時間をさいてご指導いただきありがとうございます。 川野さん両方とも上手く作動いたしました。60半ばの年齢でVBAに挑戦していますがなかなマスターできません。3日ほど考えましたがダメでしたが本当に助かりました。誠にありがとうございました。
(SoulMan)さん
ご丁寧なご指導ありがとうございました。最初川野さんに指導いただきましたので
そちらが理解し易かったのでそれで解決いたしました。
貴方のマクロもゆっくり勉強させていただきます。
ありがとうございました。
解決いたしました。(どらきち)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.