Получение уникальных значений в Excel при помощи формул только

Вот применимый класс на основе того, что сказал Constantin:

class Program
{
    static void Main(string[] args)
    {
        FastConcat<int> i = new FastConcat<int>();
        i.Add(new int[] { 0, 1, 2, 3, 4 });
        Console.WriteLine(i[0]);
        i.Add(new int[] { 5, 6, 7, 8, 9 });
        Console.WriteLine(i[4]);

        Console.WriteLine("Enumerator:");
        foreach (int val in i)
            Console.WriteLine(val);

        Console.ReadLine();
    }
}

class FastConcat<T> : IEnumerable<T>
{
    LinkedList<T[]> _items = new LinkedList<T[]>();
    int _count;

    public int Count
    {
        get
        {
            return _count;
        }
    }

    public void Add(T[] items)
    {
        if (items == null)
            return;
        if (items.Length == 0)
            return;

        _items.AddLast(items);
        _count += items.Length;
    }

    private T[] GetItemIndex(int realIndex, out int offset)
    {
        offset = 0; // Offset that needs to be applied to realIndex.
        int currentStart = 0; // Current index start.

        foreach (T[] items in _items)
        {
            currentStart += items.Length;
            if (currentStart > realIndex)
                return items;
            offset = currentStart;
        }
        return null;
    }

    public T this[int index]
    {
        get
        {
            int offset;
            T[] i = GetItemIndex(index, out offset);
            return i[index - offset];
        }
        set
        {
            int offset;
            T[] i = GetItemIndex(index, out offset);
            i[index - offset] = value;
        }
    }

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        foreach (T[] items in _items)
            foreach (T item in items)
                yield return item;
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}
75
задан Patrick Honorez 10 September 2019 в 10:51
поделиться

2 ответа

Ok, I have two ideas for you. Hopefully one of them will get you where you need to go. Note that the first one ignores the request to do this as a formula since that solution is not pretty. I figured I make sure the easy way really wouldn't work for you ;^).

Use the Advanced Filter command

  1. Select the list (or put your selection anywhere inside the list and click ok if the dialog comes up complaining that Excel does not know if your list contains headers or not)
  2. Choose Data/Advanced Filter
  3. Choose either "Filter the list, in-place" or "Copy to another location"
  4. Click "Unique records only"
  5. Click ok
  6. You are done. A unique list is created either in place or at a new location. Note that you can record this action to create a one line VBA script to do this which could then possible be generalized to work in other situations for you (e.g. without the manual steps listed above).

Using Formulas (note that I'm building on Locksfree solution to end up with a list with no holes)

This solution will work with the following caveats:

  • The list must be sorted (ascending or descending does not matter). Actually that's quite accurate as the requirement is really that all like items must be contiguous but sorting is the easiest way to reach that state.
  • Three new columns are required (two new columns for calculations and one new column for the new list). The second and third columns could be combined but I'll leave that as an exercise to the reader.
  • Here is the summary of the solution:

    1. For each item in the list, calculate the number of duplicates above it.
    2. For each place in the unique list, calculate the index of the next unique item.
    3. Finally, use the indexes to create a new list with only unique items.

    And here is a step by step example:

    1. Open a new spreadsheet
    2. В a1: a6 введите пример, указанный в исходном вопросе («красный», «синий», «красный», «зеленый», «синий», «черный»).
    3. Сортировка списка: поместите выделение в список и выберите команду сортировки.
    4. В столбце B вычислите дубликаты:
      1. В B1 введите «= ЕСЛИ (СЧЁТЕСЛИ ($ A $ 1: A1, A1) = 1,0, СЧЁТЕСЛИ (A1: $ A $ 6, A1))». Обратите внимание, что знак «$» в ссылках на ячейки очень важен, поскольку он значительно облегчит следующий шаг (заполнение остальной части столбца). Знак «$» указывает на абсолютную ссылку, поэтому при копировании / вставке содержимого ячейки ссылка не будет обновляться (в отличие от относительной ссылки, которая будет обновляться).
      2. Use smart copy to populate the rest of column B: Select B1. Move your mouse over the black square in the lower right hand corner of the selection. Click and drag down to the bottom of the list (B6). When you release, the formula will be copied into B2:B6 with the relative references updated.
      3. The value of B1:B6 should now be "0,0,1,0,0,1". Notice that the "1" entries indicate duplicates.
    5. In Column C, create an index of unique items:
      1. In C1, enter "=Row()". You really just want C1 = 1 but using Row() means this solution will work even if the list does not start in row 1.
      2. In C2, enter "=IF(C1+1<=ROW($B$6), C1+1+INDEX($B$1:$B$6,C1+1),C1+1)". The "if" is being used to stop a #REF from being produced when the index reaches the end of the list.
      3. Use smart copy to populate C3:C6.
      4. The value of C1:C6 should be "1,2,4,5,7,8"
    6. In column D, create the new unique list:
      1. In D1, enter "=IF(C1<=ROW($A$6), INDEX($A$1:$A$6,C1), "")". And, the "if" is being used to stop the #REF case when the index goes beyond the end of the list.
      2. Use smart copy to populate D2:D6.
      3. The values of D1:D6 should now be "black","blue","green","red","","".

    Hope this helps....

    53
    ответ дан 24 November 2019 в 11:38
    поделиться

    Вы можете использовать СЧЁТЕСЛИ, чтобы получить количество вхождений значения в диапазоне. Поэтому, если значение находится в A3, диапазон равен A1: A6, тогда в следующем столбце используйте IF (EXACT (COUNTIF (A3: $ A $ 6, A3), 1), A3, ""). Для формата A4 это будет IF (EXACT (COUNTIF (A4: $ A $ 6, A3), 1), A4, "")

    Это даст вам столбец, в котором все уникальные значения не дублируются

    2
    ответ дан 24 November 2019 в 11:38
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: