2

次のデータがあります。

    a b c d f g h i j
    a b d e f h i j
    a b c d e f j k l
    a b c d e f g h m

次のように(たとえばExcelに)出力したいと思います。

    a b c d e f g h i j
    a b   d e f   h i j
    a b c d e f       j k l
    a b c d e f g h         m

Excel の用語では、テキストが列内で一致するようにセルをシフトしたいと考えています。

注: 簡単にするためにアルファベット順を使用しましたが、実際にはそのような順序はありませんが、元の順序を維持する必要があります。

更新された例:

    Original Data                                                   
    a   b   c   d   f   g   h   i   j                   
    a   b   d   e   f   h   i   j                       
    a   b   c   d   e   f   j   k   l                   
    a   b   x   d   e   f   g   h   m                   

    Dougs Output                                                    
    a   b   c   d           f   g   h   i   j           
    a   b       d       e   f       h   i   j           
    a   b   c   d       e   f               j   k   l   
    a   b       d   x   e   f   g   h                   m

    My Manual Output (Required) 
    a   b   c       d       f   g   h   i   j           
    a   b           d   e   f       h   i   j           
    a   b   c       d   e   f               j   k   l   
    a   b       x   d   e   f   g   h                   m

上記の x はインデックス 2 で発生しますが、d はインデックス 2 と 3 で発生するため、x は d の前に来る必要があります。

4

2 に答える 2

0

私はそれを手に入れたと思います。これは、 に重複する値を追加できないという事実に依存していますcollection。秘訣は、ソース データを正しい順序で解析することです。私はそれを、列の各セルを通過してから次の列に進むと解釈します。コレクションには、その検索順序で見つかった各項目の最初のインスタンスが含まれます。

コードには 2 つのシートが必要です。1 つはソースを含むシートで、もう 1 つは出力を含むターゲット シートです。この場合、ワークブックの最初の 2 つのシートにコードを設定wsSourcewsTargetましたが、必要に応じて変更できます。

の定義を変更できますrng。ソース シートに他に何もない限り、コードはデータの最後の行と最後の列を決定します。これは、次の行によって行われFindます。

Sub Rearrange()
Dim wsSource As Excel.Worksheet
Dim rng As Excel.Range
Dim i As Long, j As Long
Dim cell As Excel.Range
Dim coll As Collection
Dim wsTarget As Excel.Worksheet
Dim SourceLastRow As Long
Dim SourceLastCol As Long

Set wsSource = ThisWorkbook.Sheets(1)
Set wsTarget = ThisWorkbook.Sheets(2)
Set rng = wsSource.Range("A1:i4")    'change to suit

Set coll = New Collection
SourceLastRow = rng.Cells.Find("*", rng.Cells(1), xlValues, , xlByRows, xlPrevious).Row
SourceLastCol = rng.Cells.Find("*", rng.Cells(1), xlValues, , xlByColumns, xlPrevious).Column
'cycle through the cells in the range down through each column from left to right
For i = 1 To SourceLastCol
    For j = 1 To SourceLastRow
        Set cell = wsSource.Cells(j, i)
        If cell.Value <> "" Then
            On Error Resume Next
            'can only add an item once - no duplicates
            coll.Add cell.Value, cell.Value
            On Error GoTo 0
        End If
    Next j
Next i
'Clear and re-load wsTarget
wsTarget.Cells.Clear
For i = 1 To coll.Count
    For j = 1 To SourceLastRow
        If Application.WorksheetFunction.CountIf(wsSource.Cells(j, 1).EntireRow, coll(i)) = 1 Then
            wsTarget.Cells(j, i) = coll(i)
        End If
    Next j
Next i
End Sub
于 2012-09-19T06:17:22.177 に答える
0

Javaで解決しました。各値の最大インデックスと最小インデックスを調べて並べ替えるカスタム比較があります。次に、それらを画面に印刷しました。

**ここで説明されていない理由により、私のデータは HashMap にあることに注意してください。

**経験の浅いコーディング慣行を許してください。

@ Doug-Glancy VBでできるなら、それは素晴らしいことです!

ValueComparator.java

import java.util.Comparator;
import java.util.Map;

public class ValueComparator implements Comparator<String> {

    private Map<String, Integer[]> base;

    public ValueComparator(Map<String, Integer[]> m) {
        this.base = m;
    }

    public int compare(String so1, String so2) {

        // get the max and min indices from each data peice
        Integer[] o1 = base.get(so1);
        Integer[] o2 = base.get(so2);

        // compare their min index first
        if (o1[0] < o2[0]) {
            return -1;
        }
        if (o1[0] == o2[0]) { //if they are the same
            if ( o1[1] < o2[1]) { // then look at the max index
                return -1;
            }
            else {
                return 1;
            }                   
        }
        else { 
            return 1;
        }
    }
}

App.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import localhost.ValueComparator;


public class App 
{
    public static void main( String[] args )
    {

        // create a list to store our original data
        ArrayList<HashMap<String, String>> keyValuePairs = new ArrayList<HashMap<String,String>>();

        // add the data to the list
        HashMap<String, String> a = new LinkedHashMap<String, String>();
        a.put("a", "1"); a.put("b", "1"); a.put("c", "1"); a.put("d", "1"); a.put("f", "1"); a.put("g", "1"); a.put("h", "1"); a.put("i", "1"); a.put("j", "1");
        keyValuePairs.add(a);

        HashMap<String, String> e = new LinkedHashMap<String, String>();
        e.put("a", "1"); e.put("b", "1"); e.put("d", "1"); e.put("e", "1"); e.put("f", "1"); e.put("h", "1"); e.put("i", "1"); e.put("j", "1");
        keyValuePairs.add(e);

        HashMap<String, String> b = new LinkedHashMap<String, String>();
        b.put("a", "1"); b.put("b", "1"); b.put("c", "1"); b.put("d", "1"); b.put("e", "1"); b.put("f", "1"); b.put("j", "1"); b.put("k", "1"); b.put("l", "1");
        keyValuePairs.add(b);

        HashMap<String, String> c = new LinkedHashMap<String, String>();
        c.put("a", "1"); c.put("b", "1"); c.put("x", "1"); c.put("d", "1"); c.put("e", "1"); c.put("f", "1"); c.put("g", "1"); c.put("h", "1"); c.put("m", "1");
        keyValuePairs.add(c);

        // create a map to store the max and min indices
        Map<String, Integer[]> m = new HashMap<String, Integer[]>();

        Integer curpos = new Integer(0);

        // loop through the data and find the max and min indices of each data (key)
        for ( Map<String,String> s : keyValuePairs) {
            curpos = 0;
            for ( String t : s.keySet() ) {

                if ( !m.containsKey(t) ){
                    // if its the first time to see the data, just add its current index as max and min
                    m.put(t,new Integer[] {curpos, curpos});

                }
                else {
                    // check if index is lower than existing minimum
                    Integer[] i = m.get(t);
                    if ( i[0] > curpos) {
                        m.put(t, new Integer[] {curpos, i[1]});
                    }
                    //check if index is greater than current maximum
                    if ( curpos > i[1] ) {
                        m.put(t, new Integer[] {i[0], curpos});
                    }
                }
                curpos++;
            }
        }

        System.out.println("The unsorted data");

        for ( HashMap<String,String> h : keyValuePairs ) {
            for ( String s : h.keySet() ) {
                System.out.print(" " + s + " ");
            }
            System.out.println();
        }
        System.out.println("\n");

        // Sort the data using our custom comparator
        ValueComparator com = new ValueComparator(m);
        List<String> toSort = new LinkedList<String>(m.keySet());
        Collections.sort(toSort, com);

        System.out.println("The sorted data");

        for ( HashMap<String,String> h : keyValuePairs) {

            for ( String s : toSort ) {
                if ( h.containsKey(s) ) {
                    System.out.print(s + " ");
                }
                else {
                    System.out.print("  ");
                }
            }
            System.out.println();
        }

    }

}
于 2012-09-21T05:11:13.080 に答える