获取许多唯一值,而不分离属于同一块值的值

时间:2014-12-04 11:22:22

标签: oracle vba excel-vba oracle11g access-vba

我可以使用PL / SQL解决方案或Access VBA / Excel VBA(虽然Access VBA优于Excel VBA)。所以,PL / SQL是第一选择,Access VBA是第二选择,Excel VBA是第三选。

这是一个非常难以解释的问题。请提出任何问题,我会尽力回答。

我在名为NR_PVO_120的表中有以下数据集。我如何在不排除任何传真号码下的任何其他ID的情况下挑选出一个UNIQUE OtherID的号码(可以改变但可以改为6)?

因此,如果您从Row7中选择OtherID,那么您还必须从第8行和第9行中选择OtherID,因为它们具有相同的传真号码。基本上,一旦您选择了OtherID,您就有义务选择与您选择的传真号码相同的所有其他ID。

如果请求的号码(本例中为6)不可能,那么"最接近的号码但不超过"将是规则。

例如,如果您从第1-10行获取OtherID,您将获得6个唯一的OtherID,但第10行与第11行和第12行共享传真。您需要全部使用3(但这会将唯一计数提高到8) ,这是不可接受的)或跳过此OtherID并找到一个传真,将添加1个唯一的OtherID(例如,它可以有4个OtherID,但结果集中存在3个,因此不要添加到唯一计数)。我的6个UNIQUE OtherID的结果将需要包含现有OtherID所连接的任何传真下的所有OtherID。

因此,一种解决方案是采用1-6行,26行。另一种方法是采用1-4,10-14行。还有更多,但你明白了。

将有许多可能性(真实数据集有数万行,请求的人数大约为10K),只要连接到结果集上所有传真的所有其他ID都是所请求号码的一部分(6在这种情况下)任何组合都可以。

一些笔记。

  1. 要求尽可能接近所要求的号码。

  2. 某些其他ID会有一个空白传真,它们只应作为最后的手段包含在内(对于所请求的号码,其他ID不够)。

  3. 这是怎么做到的?

    Row      OtherID        Fax
    1       11098554    2063504752
    2       56200936    2080906666
    3       11098554    7182160901
    4       25138850    7182160901
    5       56148974    7182232046
    6       56530104    7182234134
    7       25138850    7182234166
    8       56148974    7182234166
    9       11098554    7182234166
    10      56597717    7182248132
    11      56166294    7182248132
    12      25138850    7182248132
    13      56148974    7182390090
    14      56226456    7182390090
    15      56148974    7182395285
    16      25138850    7182395285
    17      56166614    7180930966
    18      11098554    7180930966
    19      56159509    7180930966
    20      25138850    7185462234
    21      56148974    7185462234
    22      25138850    7185465013
    23      56024315    7185465013
    24      56115247    7185465281
    25      25138850    7185465281
    26      56148975    7185466029
    

    一些示例输出

    一种解决方案是采用1-6行和26行。

    Row      OtherID        Fax
    1       11098554    2063504752
    2       56200936    2080906666
    3       11098554    7182160901
    4       25138850    7182160901
    5       56148974    7182232046
    6       56530104    7182234134
    26      56148975    7185466029
    

    另一种解决方案是采用1-4行和10-14行。

    Row      OtherID        Fax
    1       11098554    2063504752
    2       56200936    2080906666
    3       11098554    7182160901
    4       25138850    7182160901
    10      56597717    7182248132
    11      56166294    7182248132
    12      25138850    7182248132
    13      56148974    7182390090
    14      56226456    7182390090
    

    还有更多。

    我只需要传真作为输出。

    这是针对传真广告系列,我们需要确保没有传真号码传真两次,连接到该传真号码的所有人都会通过一个传真发送。

    因此,我们的想法是在您最终使用的任何传真下使用所有其他ID。

    编辑这里目前的工作方式,也许这有助于画一幅画

    列表按传真排序,它们从列表中下载到随机点,确认最后的记录与相同的传真结束。所以在我的例子中,他们会停在第1,2,4,5,6,9,12,14,16,19,21,23,25,26行。然后,他们会看到他们在此之前有多少独特的OtherID。如果它太多了,那就看看它们有多少。如果它太少,它们会下降一些,看看它们有多少。他们一直这样做,直到他们得到他们唯一的号码。唯一的要求是始终在传真中包含所有其他ID。

6 个答案:

答案 0 :(得分:1)

这不是一个完整的答案,但我不想在评论中写下很多疑问 您的主要目标是向人们发送信息,并避免一个人收到传真两次的情况。所以你首先需要一个独特的收件人列表,如下所示:

select distinct otherid
  from NR_PVO_120

如果一个人有两个传真号码,您需要决定选择哪一个:

select otherid, fax
  from (select otherid, fax, row_number() over (partition by otherid order by <choosing rule>) rn
          from NR_PVO_120)
 where rn = 1

(所有这些都是你在上一个问题的答案中所有)
如果您使用此传真号码列表,则所有收件人都会收到传真,每个人只能收到一份传真。但是不会使用某些传真号码。你可以很容易地找到它们:

select otherid, fax
  from (select otherid, fax, row_number() over (partition by otherid order by <choosing rule>) rn
          from NR_PVO_120)
 where rn > 1

如果您将传真发送到任何此号码,有些人会收到两次传真 英语不是我的母语,所以我不明白你说什么,而不会打破传真号码&#34;。正如我在你的问题中所看到的,你可能需要在你的问题中使用传真号码的顺序作为数字优先级(表中的数字越大 - 使用它的概率越高)。看起来你可以使用以下内容:

select otherid, fax
  from (select otherid, fax, row_number() over (partition by otherid order by row) rn
          from NR_PVO_120)
 where rn = 1

row子句中的order by是示例表中的Row

<强> UPD
P. S.关于我的上一个问题:我们有一个具有特定顺序的表,顺序很重要。我们逐行获取表格的行。取第一行并将其otheridfax放到结果表中。然后采取下一行。如果它包含另一个fax号码和otherid,我们会接受它,如果我们的结果表中已经otherid,我们会跳过它。你问过这个算法吗?

答案 1 :(得分:1)

这可以让你在标准SQL中获得大部分内容,但它并不完美,我希望MODEL clause最适合,但是...

这是做什么的,是:

  1. all_possible中计算出所有可能的组合
  2. 在此some_counting中进行调整,并计算每otherid个唯一fax的数量。我们也可以将此限制为6,以便我们排除任何永远不会符合条件的fax
  3. uniquify中使用row_number()以确保我们可以在以后otherid分割具有相同fax个数量的记录,并确定最佳记录。如果这是6,那么你就获得了简单的胜利。
  4. cumulative_sum中计算出每个传真otherid个的运行总和。这里的诀窍是你执行它的顺序。我选择先选择最好的,然后加入较小的。我确信有一种更聪明的方法可以做到这一点......我这样做是因为如果最大的是6,你就赢了。如果它是4,那么你可以用2 fax个填充它,只有1个otherid等。
  5. 最后将累计金额限制为6条记录,并提取所需的所有额外数据。
  6. 假设一张表如下,填写了您的数据:

    create table tmp_table ( 
       r number
     , otherid number
     , fax number
       );
    

    代码看起来像这样:

    with all_possible as (
    select t.r as t_r, t.otherid as t_otherid, t.fax as t_fax
         , u.r as u_r, u.otherid as u_otherid, u.fax as u_fax
      from tmp_table t
      left outer join tmp_table u
        on t.fax = u.fax
       and t.r <> u.r
           )
    , some_counting as (
     select fax 
          , count(distinct otherid) as no_o_per_fax
       from all_possible
    unpivot ( (r, otherid, fax) 
            for (a, b, c)
             in ( (t_r, t_otherid, t_fax)
                , (u_r, u_otherid, u_fax)
                ))
     group by fax
    having count(distinct otherid) < 6            
            )
    , uniquify as (
    select c.*
         , row_number() over (order by no_o_per_fax asc) as rn
         , max(no_o_per_fax) over () as m_fax
      from some_counting c
           )
    , cumulative_sum as (
    select u.*, sum(no_o_per_fax) over (order by case when no_o_per_fax = m_fax then 0 else 1 end
                                            , no_o_per_fax asc 
                                            , rn ) as csum
      from uniquify u
           )
    , candidates as (
    select a.*
      from cumulative_sum a
     where csum <= 6
           )
    select b.*
      from tmp_table a
      join candidates b
        on a.fax = b.fax
    

    SQL Fiddle

    我在这里广泛使用公用表表达式来使代码看起来更干净

答案 2 :(得分:1)

如果我理解正确的要求,就应该这样做。

编辑:我错过了唯一性要求。所以,我已经更新了代码来解释这个问题。

EDIT2:使用记录类型将传真添加到输出中。

declare
    input_number int := 6;
    cursor get_faxes is
           select fax, count(*) num_ids from listofids
            group by fax
            order by fax;
    cursor get_ids (p_fax in int) is
           select otherid from listofids
             where fax = p_fax;
    type idrec is record(id listofids.otherid%type, fax listofids.fax%type);
    type idlist is table of idrec;
    output_list idlist := idlist();
    v_memberof  boolean;
begin
    for fax_rec in get_faxes loop
        if output_list.count + fax_rec.num_ids <= input_number then
            for id_rec in get_ids(fax_rec.fax) loop
                v_memberof := False;
                for i in 1..output_list.count loop
                    if output_list(i).id = id_rec.otherid then
                        v_memberof := true;
                    end if;
                end loop;
                if not v_memberof then
                    output_list.extend(1);
                    output_list(output_list.count).id := id_rec.otherid;
                    output_list(output_list.count).fax := fax_rec.fax;
                end if;
            end loop;
        end if;
    end loop;
    for i in 1..output_list.last loop
        dbms_output.put_line('id: ' || output_list(i).id || '  fax:' || output_list(i).fax);
    end loop;
end;

现在返回以下内容:

id: 11098554  fax:2063504752
id: 56200936  fax:2080906666
id: 56166614  fax:7180930966
id: 56159509  fax:7180930966
id: 25138850  fax:7182160901
id: 56148974  fax:7182232046

如果您确实需要随机选择,则可以通过使用dbms_random.random而不是传真来更改顺序。

答案 3 :(得分:1)

编辑2/13/2015 在使用接受的答案几个月后,我遇到了一个尚未发生的情景,并意识到他的解决方案只有在我需要得到一个不太接近总数的数字时才有效。例如,如果我的总记录数是15000并且我要求12000,那么他的代码将给出10或11k。如果我要求8k,那么我可能会得到8。

我不明白他的代码是做什么的,他从不回复所以我无法解释为什么会发生这种情况,我的猜测是他按照一定的顺序接受了计数,因为结果取决于传真的排序顺序 - 他不一定每次都能得到最好的结果。 当有足够的空间(从15k中获得8l)时,他有足够的空间进行任何组合以产生可接受的结果但是一旦你要求更紧的数字(15k中的12k),他就会被锁定在他的命令中并且足够快地用完了可接受的计数。

所以这是无论如何都能得到正确结果的代码。它不是那么优雅,而且速度极慢但是很有效。

12/13/14我认为我得到它,PL / SQL,到目前为止不是最好的解决方案,但它提供了比他们目前手工获得的更好的结果。实际上,真的很想知道可能存在的问题

12/13/14编辑接受的答案就是这样做的方式,我只是留在这里作为对比,所以人们可以看到如何不编码大声笑。

DECLARE
     CountsNeededTotal NUMBER;
     CountsNeededRemaining NUMBER;
     CurCountsTotal NUMBER;
     CurFaxCount NUMBER;
     CurFaxCountPicked NUMBER;
BEGIN
     CountsNeededTotal := 420;
     CurCountsTotal := 0;
     CurFaxCount := 0;

     CountsNeededRemaining := CountsNeededTotal - CurCountsTotal;

     EXECUTE IMMEDIATE 'TRUNCATE TABLE NR_PVO_121';


     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --START BLOCK
     --this block jsut gets the first fax, the fax with the largest number of people
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################

     --get the first fax with the most people as long as thta number isn't larger than the number needed
     SELECT MAX(CountOfPeople) CountOfPeople
    INTO CurFaxCount
    FROM (SELECT     fax
            ,COUNT(1) CountOfPeople
           FROM NR_PVO_120
          GROUP BY Fax
         HAVING COUNT(1) <= CountsNeededRemaining);

     COMMIT;

     --if there is a number that's not larger then add to the table and keep looping
     --if there isn't then there's no providers from this campaign that can be used
     IF CurFaxCount >= 0 THEN
       --insert into the 121 table (final list of faxes)
       INSERT INTO NR_PVO_121
         SELECT   fax
              ,COUNT(1) CountOfPeople
             FROM NR_PVO_120
           HAVING COUNT(1) = (SELECT MAX(CountOfPeople) CountOfPeople
                       FROM (SELECT   fax
                               ,COUNT(1) CountOfPeople
                              FROM NR_PVO_120
                          GROUP BY Fax
                            HAVING COUNT(1) <= CountsNeededTotal))
         GROUP BY Fax;



       COMMIT;

       --############################################################################################
       --############################################################################################
       --############################################################################################
       --############################################################################################
       --############################################################################################
       --START BLOCK
       --this block loops through remaining faxes
       --############################################################################################
       --############################################################################################
       --############################################################################################
       --############################################################################################
       --############################################################################################



       SELECT SUM(CountOfPeople) INTO CurCountsTotal FROM NR_PVO_121;


       IF CurCountsTotal < CountsNeededTotal THEN
         CountsNeededRemaining := CountsNeededTotal - CurCountsTotal;


         --loop until counts needed remaining is 0 or as close as 0 as possible without going in the negative
         WHILE CountsNeededRemaining >= 0 LOOP
              --clear 122 table
              EXECUTE IMMEDIATE 'TRUNCATE TABLE NR_PVO_122';


              --loop through all faxes in 120 table  MINUS the ones in the 121 table
              DECLARE
                CURSOR CurRec  IS
                  SELECT DISTINCT Fax
                    FROM NR_PVO_120
                   WHERE Fax NOT IN (SELECT Fax FROM NR_PVO_121);
                PVO CurRec%ROWTYPE;
              BEGIN
                OPEN CurRec;
                LOOP
                  FETCH CurRec INTO PVO;

                  SELECT DISTINCT COUNT(OtherID) CountOfPeople
                    INTO CurFaxCount
                    FROM NR_PVO_120
                   WHERE     Fax = PVO.fax
                      AND OtherID NOT IN (SELECT DISTINCT OtherID
                                   FROM NR_PVO_120
                                  WHERE fax IN (SELECT Fax FROM NR_PVO_121));
                  --                                                          DBMS_OUTPUT.put_line('CurFaxCount ' || CurFaxCount);
                  --                                                          DBMS_OUTPUT.put_line('CountsNeededRemaining ' || CountsNeededRemaining);

                  IF CurFaxCount <= CountsNeededRemaining THEN
                    --record their unique counts in 122 table IF THEY'RE NOT LARGER THAN CountsNeededRemaining
                    INSERT INTO NR_PVO_122
                         SELECT PVO.fax
                            ,CurFaxCount
                        FROM DUAL;

                    COMMIT;
                  END IF;
                  EXIT WHEN CurRec%NOTFOUND;
                --end fax loop
                END LOOP;
                CLOSE CurRec;
              END;


              --pick the highest count from 122 table
              SELECT MAX(CountOfPeople) CountOfPeople INTO CurFaxCountPicked FROM NR_PVO_122;

              --add this fax to the 121 table
              INSERT INTO NR_PVO_121
                SELECT MIN(Fax) Fax
                   ,CurFaxCountPicked
                  FROM NR_PVO_122
                 WHERE CountOfPeople = CurFaxCountPicked;


              COMMIT;
              --add the counts to the CurCountsTotal
              CurCountsTotal := CurCountsTotal + CurFaxCountPicked;
              --recalc   CountsNeededRemaining
              CountsNeededRemaining := CountsNeededTotal - CurCountsTotal;
              --
              --                                                          DBMS_OUTPUT.put_line('CurCountsTotal ' || CurCountsTotal);
              --                                                          DBMS_OUTPUT.put_line('CurFaxCountPicked ' || CurFaxCountPicked);
              --                                                          DBMS_OUTPUT.put_line('CurFaxCount ' || CurFaxCount);
              --                                                          DBMS_OUTPUT.put_line('CountsNeededRemaining ' || CountsNeededRemaining);
              --                                                          DBMS_OUTPUT.put_line('CountsNeededTotal ' || CountsNeededTotal);

              --clear 122 table
              EXECUTE IMMEDIATE 'TRUNCATE TABLE NR_PVO_122';
         --end while loop
         END LOOP;
       END IF;
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --END BLOCK
     --this block loops through remaining faxes
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################
     --############################################################################################



     END IF;
--############################################################################################
--############################################################################################
--############################################################################################
--############################################################################################
--############################################################################################
--END BLOCK
--this block jsut gets the first fax, the fax with the largest number of people
--############################################################################################
--############################################################################################
--############################################################################################
--############################################################################################
--############################################################################################



END;

这是一个更好的版本,比上面更快但在某些情况下它可能不会返回完美的结果。我在测试时无法得到错误的结果,但有可能因为我没有尝试所有可能的组合(如在第一个版本中),需要几天才能完成20K记录的数据集

DECLARE
    CountsNeededTotal NUMBER;
    CountsNeededRemaining NUMBER;
    CurCountsTotal NUMBER;
BEGIN
    CurCountsTotal := 0;

    SELECT NoOfProvToKeep INTO CountsNeededTotal FROM NR_PVO_121;

    CountsNeededRemaining := CountsNeededTotal - CurCountsTotal;

    EXECUTE IMMEDIATE 'TRUNCATE TABLE nr_pvo_122';


    COMMIT;

    IF CurCountsTotal <= CountsNeededTotal THEN
        --loop until counts needed remaining is 0 or as close as 0 as possible without going in the negative
        WHILE CountsNeededRemaining > 0 LOOP
            --clear 122 table
            INSERT INTO NR_PVO_122
                SELECT Fax
                      ,CountOfPeople
                  FROM (SELECT   DISTINCT COUNT(OtherID) CountOfPeople
                               ,Fax
                       FROM NR_PVO_120
                      WHERE OtherID NOT IN (SELECT DISTINCT OtherID
                                    FROM NR_PVO_120
                                   WHERE fax IN (SELECT Fax FROM NR_PVO_122))
                     HAVING COUNT(1) <= CountsNeededRemaining
                        GROUP BY fax
                        ORDER BY 1 DESC)
                 WHERE ROWNUM = 1;



            SELECT SUM(CountOfPeople) INTO CurCountsTotal FROM NR_PVO_122;

            COMMIT;
            --recalc   CountsNeededRemaining
            CountsNeededRemaining := CountsNeededTotal - CurCountsTotal;
        --
        --DBMS_OUTPUT.put_line('CurCountsTotal ' || CurCountsTotal || ', CountsNeededRemaining ' || CountsNeededRemaining);
        --end while loop
        END LOOP;
    END IF;



    DELETE FROM NR_PVO_112
          WHERE NVL(Fax, '999999999999') NOT IN (SELECT Fax FROM NR_PVO_122);
END;

答案 4 :(得分:0)

不确定您的要求,但这是我理解您的最佳问题。 首先,代码在传真上对数据进行排序,然后首次提取传真出现的ID,即使之后由于数据,也存在重复ID,因此再次排序和删除重复项。

Sub Unique_fax()

查找最后一行,以便循环可以多次运行

lastrow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row

将数据复制到新行,以便原始数据保持不变

For i = 1 To lastrow

Worksheets("Sheet1").Cells(i, 5).Value = Trim(Worksheets("Sheet1").Cells(i, 1))
Worksheets("Sheet1").Cells(i, 6).Value = Trim(Worksheets("Sheet1").Cells(i, 2))
Worksheets("Sheet1").Cells(i, 7).Value = Trim(Worksheets("Sheet1").Cells(i, 3))

Next

根据传真

对数据进行排序
Range("E1:G" & lastrow).Select
    Selection.Sort Key1:=Range("G1"), Order1:=xlAscending, _
                   Header:=xlNo, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom

将传真不同的ID复制到新行

x = 1
For i = 1 To lastrow
If Cells(i, 7) <> Cells(i + 1, 7) Then
Cells(x, 9) = Cells(i, 6)
x = x + 1
End If
Next

对ID列表进行排序并删除重复项

lastrowUnq = Worksheets("Sheet1").Cells(Rows.Count, 9).End(xlUp).Row

Range("I1:I" & lastrowUnq).Select
    Selection.Sort Key1:=Range("I1"), Order1:=xlAscending, _
                   Header:=xlNo, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
y = 1
For j = 1 To lastrow
If Cells(j, 9) <> Cells(j + 1, 9) Then
Cells(y, 11) = Cells(j, 9)
y = y + 1
End If
Next

End Sub

列 - A,B,C是您的原始数据。 列 - E,F,G是在传真上排序的数据。 列 - 我包含传真唯一的ID列表。 列 - K包含最终的ID列表(根据需要)。

enter image description here

答案 5 :(得分:0)

开始时测试的数据。注意其他ID在Col A中,在Col B中为传真:Before 首先,我们将找到您想要的唯一ID的数量注意:您需要一个新的表格,并且#34;使用我&#34;。我们需要一个自定义功能。此函数可以作为具有语法=UniqueItems(B2:D5)的单元格公式运行,但我们将在Sub中使用它:

Function UniqueItems(ArrayIn, Optional Count As Variant) As Variant
'   Accepts an array or range as input
'   If Count = True or is missing, the function returns the number of unique elements
'   If Count = False, the function returns a variant array of unique elements
    Dim Unique() As Variant ' array that holds the unique items
    Dim Element As Variant
    Dim i As Integer
    Dim FoundMatch As Boolean
'   If 2nd argument is missing, assign default value
    If IsMissing(Count) Then Count = True
'   Counter for number of unique elements
    NumUnique = 0
'   Loop thru the input array
    For Each Element In ArrayIn
        FoundMatch = False
'       Has item been added yet?
        For i = 1 To NumUnique
            If Element = Unique(i) Then
                FoundMatch = True
                Exit For '(exit loop)
            End If
        Next i
AddItem:
'       If not in list, add the item to unique list
        If Not FoundMatch And Not IsEmpty(Element) Then
            NumUnique = NumUnique + 1
            ReDim Preserve Unique(NumUnique)
            Unique(NumUnique) = Element
        End If
    Next Element
'   Assign a value to the function
    If Count Then UniqueItems = NumUnique Else UniqueItems = Unique
End Function

以下是您需要查找唯一ID并将其复制到工作表中的子项&#34;使用我&#34;

Sub FaxesToUse()
    Dim LastRow As Long, CurRow As Long, UniqueTotal As Long, SubTotal As Long

    UniqueTotal = InputBox("How Many Unique OtherIDs is Max?")
    If Not UniqueTotal > 0 Then
        Exit Sub
    End If

    LastRow = Range("A" & Rows.Count).End(xlUp).Row
    SubTotal = 0
    For CurRow = 2 To LastRow
        SubTotal = UniqueItems(Range("A2:A" & CurRow))
        If SubTotal > UniqueTotal Then
            SubTotal = UniqueItems(Range("A2:A" & CurRow - 1))
            Range("A1:B" & CurRow - 1).Copy
            Sheets("Use Me").Cells.Clear
            Sheets("Use Me").Range("A1").PasteSpecial xlPasteValues
            Sheets("Use Me").Activate
            MsgBox "Use Me Sheet rows contain " & SubTotal & " Unique OtherIDs"
            Exit Sub
        End If
        Cells(CurRow, 1).EntireRow.Interior.Color = RGB(255, 255, 0)
    Next CurRow

End Sub

这将为您提供如下所示的页面:After Faxes Runs现在我们只需要使用此宏删除所有重复的传真:

Sub RemoveDups()

Dim CurRow As Long, LastRow As Long, LastCol As Long, DestLast As Long, DestRng As Range, ws As Worksheet

Set ws = Sheets("Use Me")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row

For CurRow = LastRow To 3 Step -1
     Set DestRng = ws.Range("B2:B" & CurRow - 1).Find(ws.Range("B" & CurRow).Value, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext)
     If DestRng Is Nothing Then
         'Do Nothing
     Else
        DestLast = ws.Cells(DestRng.Row, Columns.Count).End(xlToLeft).Column + 1
        ws.Cells(DestRng.Row, DestLast).Value = ws.Cells(CurRow, 1).Value
        ws.Cells(CurRow, 1).EntireRow.Delete xlShiftUp
     End If
     Next CurRow
ws.Columns("B:B").Cut
ws.Columns("A:A").Insert Shift:=xlToRight
Application.CutCopyMode = False

LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
LastCol = 0
For CurRow = 2 To LastRow
    If ws.Cells(CurRow, Columns.Count).End(xlToLeft).Column > LastCol Then
        LastCol = ws.Cells(CurRow, Columns.Count).End(xlToLeft).Column
    End If
Next CurRow

MsgBox "Use Me Sheet Rows contain " & UniqueItems(ws.Range(Cells(2, 2), Cells(LastRow, LastCol))) & " Unique OtherIDs"

End Sub

请留下这个:After Remove Dups