3

文字列を想定します。

item1, item1N, item1Z, item1fhg, item1_any_letters, item2, item3, item3N, item3H

私の目標出力は単純です

item1, item2, item3

これは現在約100,000行のExcelファイルですが、一時的に必要に応じて別のプログラムなどに移行できます。

基本的に、数字の後の文字に関係なく、重複(数字で終わる最初のフレーズ)を判別する必要があります。一部のフレーズには、たとえば「ブランドアイテム2、ブランドアイテム34」も含まれる場合があります。重複の唯一の決定要因は、番号の後のすべての用語です。

これからどこから始めるべきかについてのアイデアはありますか?各文字列には通常、コンマとスペースで区切られた2〜500の値が含まれます。最終値の後にコンマはありません。

4

3 に答える 3

3
Sub Tester()

    Dim re As Object, match As Object
    Dim dict As Object
    Dim arr, arrItems, x As Long, y As Long
    Dim val, matches, valMatch


    Set dict = CreateObject("scripting.dictionary")
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "([\w ]+\d+)"
    re.ignorecase = True
    re.Global = True

    arr = ActiveSheet.Range("A1:A100").Value

    For x = LBound(arr, 1) To UBound(arr, 1)
        arrItems = Split(arr(x, 1), ",")
        dict.RemoveAll
        For y = LBound(arrItems) To UBound(arrItems)

            val = Trim(arrItems(y))

            If re.Test(val) Then
               Set matches = re.Execute(val)
               valMatch = matches(0).Value
               If Not dict.exists(valMatch) Then dict.Add valMatch, 1
            End If
        Next y

        Debug.Print arr(x, 1)
        Debug.Print Join(dict.keys, ",") 'where do you want this?

    Next x

End Sub
于 2012-06-27T00:01:03.600 に答える
2

最初の経路のTimと似たVBAアプローチ

  1. を使用しRegExpて、無効な文字(数字の後およびコンマの前の文字)を削除します

  2. a )使用Dictionary
    b)Excelの組み込みの重複削除機能(シートへの書き込み)を使用して重複を排除します

    Const strDelim = ", "
    
    Sub TestMe()
    Dim strTest As String
    Dim x
    strTest = "item1, item1N, item1Z, item1fhg, item1_any_letters, item2, item3, item3N, item3H"
    x = Split(DeDupe(strTest), strDelim)
    'fix last element
    x(UBound(x)) = Left$(x(UBound(x)), Len(x(UBound(x))) - 1)
    Call Method2(x)
    End Sub
    
    Sub Method2(ByVal x)
    Dim objDic As Object
    Dim y As Variant
    Set objDic = CreateObject("Scripting.Dictionary")
    Dim lngRow As Long
    For lngRow = LBound(x) To UBound(x)
    objDic(x(lngRow)) = 1
    Next lngRow
    MsgBox Join(objDic.keys, strDelim)
    End Sub      
    
    Function DeDupe(strIn As String) As String
    Dim objRegex As Object
    Set objRegex = CreateObject("vbscript.regexp")
    With objRegex
    .Global = True
    .Pattern = "(.+?\d+)[^\d]+(,|$)"
    DeDupe = .Replace(strIn, "$1,")
    End With
    End Function
    

Option B

    'another potential option. Not applied in this code
    Sub Method1(ByVal x)
    Dim y As Variant
    Dim rng1 As Range
    With ActiveSheet
    .[a1].Resize(UBound(x) + 1, 1) = Application.Transpose(x)
    .Columns("A").RemoveDuplicates Columns:=1, Header:=xlNo
    y = Application.Transpose(Range([a1], Cells(Rows.Count, "A").End(xlUp)))
    End With
    MsgBox Join(y, strDelim)
    End Sub
于 2012-06-27T00:20:19.670 に答える
0

これは、右端の数字以外の文字列のみを削除するクイックハックであるため、おそらく不完全です。ニーズに合わせて調整するには、正規表現の知識が必要になります。

とにかく、ここに記載されている「インストール」手順に従って、モジュールを保存すると、シートに次のような式を書き込むことができます。

=S(A1;"[^0-9]*$";"")

たとえば、B1セルで。A1セルに「Item1234blahblah」が含まれている場合、B1には「Item1234」が含まれるようになります。列Bのすべてのセルに数式をドラッグし、値を別のExcelファイルに保存して並べ替えます(または、並べ替えと小計をその場で試すことができます)。

残念ながら、100,000以上のセルでこれを行うことが実用的であるとは思いません(インプレースで小計することはお勧めしません)。

Windows用のtextools(sed、grep、uniq ...)をインストールし、フィルターを介してファイルを実行することで、はるかに優れたサービスを提供できます。各行が上記のように1つのアイテムを表すと仮定すると、次のようなフィルター

sed -e 's/^\([^0-9][^0-9]*[0-9][0-9]*\).*/\1/g' | sort | uniq -c | sort -rn

100,000行のファイルを取得し、次のようなものを返します

79283 Item 1
 1234 Item 2
  993 Item 3
  ..........

(一部のプラットフォームでは、([^ 0-9] ...の代わりに(\ D + \ d +)を記述できますが、Windowsの動作はわかりません)。

ツールのさらに良い選択は、CSVもサポートしている(Strawberry)Perl、またはPython言語です。

于 2012-06-26T22:14:56.790 に答える