[[20180525035350]] 『数値の照合について2』(ヤイリ) ページの最後に飛ぶ

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

 

『数値の照合について2』(ヤイリ)

[[20170728033732]] で
下記のようなご提案で
クローズしたのですが・・・

【元データ】

 532
 100
 558
 50
 400
 454
 【引抜依頼】
 100
 50
 400
 【引抜結果】
 100: 2行目
 50: 4行目
 400:5行目

    Option Explicit
    Type FileConfig
        Path As String 'ファイルパス
        Num  As Long   'ファイルNo
        tmp  As String '値
        cnt  As Long   '行番号
    End Type
    Sub Main()
        '//元データ配列の読込
        Dim dic As Object
        Set dic = CreateObject("Scripting.Dictionary")
        Dim Data As FileConfig
        With Data
            .Path = "C:\本データ.txt"
            .Num = FreeFile
            .cnt = 1
            Open .Path For Input As #.Num
            Do Until (EOF(.Num))
                Input #.Num, .tmp
                dic(.tmp) = dic(.tmp) & " " & .cnt '//連想配列 値に対して、行番号を入れる
                .cnt = .cnt + 1
            Loop
            Close #.Num
        End With

        '//引抜依頼と照合
        Dim rows() As String
        ReDim rows(1 To dic.Count)

        Dim PicUp As FileConfig
        With PicUp
            .Path = "C:\引抜依頼.txt"
            .Num = FreeFile
            .cnt = 1
            Open .Path For Input As #.Num
            Do Until (EOF(.Num))
                Input #.Num, .tmp
                rows(.cnt) = .tmp & ":" & Trim(dic(.tmp)) & "行目 引抜照合しました"  '//値を渡して、元データの行番号を得る
                .cnt = .cnt + 1
            Loop
            Close #.Num
        End With

        '//書き込み
        Dim OutPut As FileConfig
        With OutPut
            .Path = "C:\引抜結果.txt"
            .Num = FreeFile
            .cnt = 1
            Open .Path For Output As #.Num
            For .cnt = 1 To UBound(rows)
                Print #.Num, rows(.cnt)  '//照合で取得したデータを書き込む
            Next .cnt
            Close #.Num
        End With
        Set dic = Nothing
        MsgBox "出力完了しました"
    End Sub

(1)【元データ】

 532,あああ,東京
 100,あああ,大阪
 558,あああ,名古屋
 50,あああ,香川
 400,あああ,熊本
 454,あああ,沖縄

 (2)【引抜依頼】
 100
 50
 400

 (3)【引抜結果】
 100,あああ,大阪,2行目
 50,あああ,香川,4行目
400,あああ,熊本,5行目

引抜き結果を【元データ】から
行単位で出力し
何行目かを表示させたいのですが
困ってます。

今回はたまたま元データのマッチさせたい
データがAセルですが、ほかのセルの場合も
ございます。

アドバイスいただけたら助かります。
お手数ですが
宜しくお願いいたします。

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


 >今回はたまたま元データのマッチさせたい
 >データがAセルですが、ほかのセルの場合も
 >ございます。

ぱっとみ、シート上にデータを展開してなさそうですが、
A列とかB列とか、
テキストファイルをシート上に展開して目視で行を操作したいっていうことですか?
エクセルで全部を表示できるなら、
そのテキストファイルをエクセルで開けば、
Match関数やVLookup関数、
あるいはオートフィルターやフィルターオプションなどの
エクセルの機能を使ってどうにか出来るんじゃないでしょうか?
ご自分で応用できないマクロなんてものに頼るなら、その前に
エクセルをちゃんと使えるように勉強した方がお得だと思います。

(まっつわん) 2018/05/25(金) 08:25


すいません。
>今回はたまたま元データのマッチさせたい
 >データがAセルですが、ほかのセルの場合も
 >ございます。
は忘れてください。
これだと、仕様によって対応出来るように
依頼しているみたいですね。
シート上で展開して目視する方法ではございません。
ご指摘ありがとうございました。
(ヤイリ) 2018/05/25(金) 08:53

 >これだと、仕様によって対応出来るように
 >依頼しているみたいですね。
意味がよくわかりませんが、
現状のマクロが、行番号だけを返すのを、

「ヒットしたデータの全項目+行番号」

としたいということなんですね。
現状のやり方を改変してとなると、
そのコードを解読しないといけないので、
それは、他の方の回答をお待ちください。

 >シート上で展開して目視する方法ではございません。
いやー。最終目標が手動でのデータ削除なんですよね?
折角エクセルを使うんだし、
折角VBA使うんだから、
エクセルで自動で削除したらいいんじゃないかなぁと、思っただけです。
何十万行の中から行番号が解ったところで、手動で探すのは結構大変だろうなぁと
思うのですが。。。

(まっつわん) 2018/05/25(金) 10:03


Dictionaryオブジェクトの使い方がちょっと変です。 データに重複が無ければ問題は出ないでしょうけど、重複していたら簡単に崩れます。 正攻法で、辞書にあれば追記、無ければキー追加するようにすべきでしょう。
Type宣言も、構成を面倒にしているだけで、あまり役に立っていないので、排除して書き直してみます。これなら、新しい方のファイルレイアウトでも対応できるでしょう。

 Sub test()
    Dim DIC As Object
    Dim NUM1 As Long
    Dim NUM2 As Long
    Dim tmp As String
    Dim cnt As Long
    Dim vw As Variant

    Set DIC = CreateObject("Scripting.Dictionary")

    NUM1 = FreeFile()
    Open "C:\本データ.txt" For Input As #NUM1
    Do Until (EOF(NUM1))
        cnt = cnt + 1
        Line Input #NUM1, tmp
        vw = Split(tmp, ",")
        If DIC.exists(vw(0)) = True Then
            DIC(vw(0)) = DIC(vw(0)) & " " & cnt
        Else
            DIC.Add vw(0), tmp & "," & cnt
        End If
    Loop
    Close #NUM1

    NUM1 = FreeFile()
    Open "C:\引抜依頼.txt" For Input As #NUM1
    NUM2 = FreeFile()
    Open "C:\引抜結果.txt" For Output As #NUM2
    Do Until (EOF(NUM1))
        Line Input #NUM1, tmp
        If DIC.exists(tmp) = True Then
            Print #NUM2, DIC(tmp) & "行目"
        End If
    Loop
    Close #NUM2
    Close #NUM1
 End Sub
(???) 2018/05/25(金) 13:39

補足。
重複対応している処理なのに重複するデータ例がないし、重複時はどう表示したいのか判らないので、行だけスペースで区切って並べています。行以外も出力したい場合は、ご自身で修正してみてください。
(???) 2018/05/25(金) 13:42

(???)さん。
サンプルコードありがとうございます。
ご提示いただきました配列の最後のエリアは
こちらで考えますのでありがとうございました。

最後もう1点だけお聞きしたいのですが
本データの
Aセルをマッチさせたいとき
DIC.Add vw(0)
Bセルをマッチさせたいとき
DIC.Add vw(1)と
なると思いますが

AセルとBセル両方マッチさせたいとき
添え字の書き方をご教授願えないでしょうか?
お手数おかけいたしますが
どうぞよろしくお願いいたします。

 (1)【元データ】

 532,1,あああ,東京
 100,2,あああ,大阪
 558,3,あああ,名古屋
 50,4,あああ,香川
 400,5,あああ,熊本
 454,6,あああ,沖縄

 (2)【引抜依頼】
 100,2
 50,4
 400,5

(3)【引抜結果】

 100,2,あああ,大阪,2行目
 50,4,あああ,香川,4行目
400,5,あああ,熊本,5行目

(ヤイリ) 2018/05/26(土) 00:24


Dictionaryを理解してください。
私のコードでは、カンマ区切りの一番左の文字列をキーに、読み込んだ1行全部と、何行目かの情報をアイテムに代入しています。そして、キーが一致したものを書き出しています。 キーは完全一致しか判定できず、曖昧検索はできません。

そのままだと1列しか探せないので、2列の一致で探したいならば、少し工夫する必要があります。 vw(0) & "," & vw(1) をキーにすれば以下のようになるので、目的が果たせるのではないでしょうか。

キー1:532,1
アイテム1:532,1,あああ,東京,1

キー2:100,2
アイテム2:100,2,あああ,大阪,2

DIC("100,2") は、アイテム2を返す事になります。
(???) 2018/05/26(土) 22:05


コメントありがとうございます。

vw = Split(tmp, ",")で
配列を返してましたので
vw(0) & vw(1) 
上記のような認識でした。

vw(0) & "," & vw(1)で対応できましたので
参考にさせていただきます。
サンプルコード
どうもありがとうございました。
(ヤイリ) 2018/05/26(土) 23:13


たびたびすいません。
仕様が変わって困っているのですが・・・

(1)【元データ】と(2)【引抜依頼】のAセルが
マッチした場合
(1)【元データ】と(2)【引抜依頼】
配列を結合したいのですが
アドバイスいただけないでしょうか。
たびたびで恐縮ですがよろしくお願いいたします。

(1)【元データ】

 532,1,あああ,東京
 100,2,あああ,大阪
 558,3,あああ,名古屋
 50,4,あああ,香川
 400,5,あああ,熊本
 454,6,あああ,沖縄

 (2)【引抜依頼】
 100,1500円
 50,2000円
 400,5000円

(3)【引抜結果】

 100,2,あああ,大阪,100,1500円,2行目
 50,4,あああ,香川,50,2000円,4行目
400,5,あああ,熊本,400,5000円,5行目

(ヤイリ) 2018/06/05(火) 20:25


【引抜依頼】のファイルを読み込む際、変数tmp 1つに読み込んでいますが、これをSplitで分けるか、または Line Input 1回を Input 2回に変えるかして、2つの変数に分けましょう。 DICを探すのは1つ目の変数だけで良いですよね。

次に、DIC(tmp) の中身は「100,2,あああ,大阪,2」のように行番号を付けてしまっています。出力が「100,2,あああ,大阪,2行目,1500円」のように、最後に金額を追加するなら簡単ですが、行の前に挿入してますよね。 順番なんてどっちでも良いでしょうに、何でわざわざ処理を難しくするのやら…。

挿入するには、一旦 DIC(tmp) で得られる情報をSplitでまたばらばらにしてから、カンマ付けながら再度文字列連結していきましょう。 バラして、くっつけて、またバラして、またくっつける…。 まったく美しくない処理です。 いっそ、【引抜依頼】の方を辞書化して、【引抜依頼】を1行読む毎に判定するように作り直す方が、修正量多いですが、無駄が減りますね。
(???) 2018/06/06(水) 09:34


アドバイスどうもありがとうございます。
配列の結合の順番はどっちでも良かったのですが、
明確に仕様をお伝えしたほうが
アドバイスをいただきやすいと思いまして・・・
今回は、急ぎなので、別の方法で対応し、
引き抜き対象が500か所以内の固定でしたので
マッチングというより
条件を複数書いて、データをはきだすことにしました。

因みにアドバイスいただいたので
実際やってみます。
またなにかございましたら
どうぞよろしくお願いいたします。
ありがとうございました。

(ヤイリ) 2018/06/07(木) 20:18


コメント返信:

[ 一覧(最新更新順) ]


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