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. 诀窍是以正确的顺序解析源数据。我将其解释为向下遍历一列中的每个单元格,然后转到下一列。然后,该集合包含在该搜索顺序中找到的每个项目的第一个实例。

该代码需要两张表,一张带有源表,一张目标表包含输出。在这种情况下,我使用代码设置工作簿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 中使用,那就太好了!

值比较器.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;
        }
    }
}

应用程序.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 回答