Генерация дубликатов строк
В большинстве случаев повторы в наших данных нежелательны и мы с вами стараемся от них избавиться разными способами. Но иногда случается, что дубликаты нужны и полезны, и более того - нам необходимо их создавать!
Допустим, что у нас есть вот такая таблица с именами людей, заказавших билет в кино и количеством билетов для каждого:
Каждому билету нужно присвоить уникальный 6-значный номер, который формируется здесь простой функцией СЛУЧМЕЖДУ (RANDBETWEEN), генерирующей целое случайное число в заданном диапазоне 100000-999999. Да, я знаю, что теоретически совпадения могут быть, но вероятность очень невелика и пока нас, допустим, устраивает (кого не устраивает - см.эту статью). Проблема в другом: для тех, кто заказал больше одного билета, нужно вставить в таблицу новые строки-дубли (по количеству заказанных билетов), т.е. на выходе получить вот такое:
Руками такое делать - тоскливо, формулами - сложно. Так что остаются два наиболее удобных варианта - макросы и Power Query.
Способ 1. Создание дубликатов строк макросом
Откроем редактор макросов кнопкой Visual Basic на вкладке Разработчик (Developer) или сочетанием клавиш Alt+F11. Вставим новый модуль через меню Insert - Module и скопируем туда текст нашего макроса:
Sub Duplicate_Rows() Dim cell As Range Set cell = Range("B2") 'первая ячейка в столбце с кол-вом билетов Do While Not IsEmpty(cell) If cell > 1 Then cell.Offset(1, 0).Resize(cell.Value - 1, 1).EntireRow.Insert 'вставляем N пустых строк cell.Resize(cell.Value, 1).EntireRow.FillDown 'заполняем вниз из первых ячеек End If Set cell = cell.Offset(cell.Value, 0) Loop End Sub
Принцип тут не самый сложный:
- проходим сверху-вниз по столбцу начиная с B2 до первой пустой ячейки
- если число в ячейке >1, то вставляем пустых строк под ячейкой на одну меньше, чем число билетов
- заполняем пустые ячейки (метод FillDown - аналог "протягивания за черный крестик" в правом нижнем углу ячейки)
- переходим к следующей ячейке и т.д.
Способ 2. Создание дубликатов строк в Power Query
Тем, кто хотя бы немного сталкивался с Power Query, рекламировать его мощь не нужно :) Для тех, кто не знаком (если коротко), то Power Query - это бесплатная надстройка для Excel от Microsoft, умеющая делать с данными практически все, что только можно себе представить: загрузку из любых источников, очистку, трансформацию, анализ данных и т.д. Для Excel 2010-2013 ее можно скачать с сайта Microsoft (появится отдельная вкладка Power Query после установки), а в Excel 2016 она уже встроена по-умолчанию (группа Получить внешние данные на вкладке Данные).
Power Query может легко и красиво решить нашу проблему с генерацией дубликатов.
Для начала, выделим нашу таблицу и загрузим ее в Power Query кнопкой Из таблицы/диапазона (From Table/Range) на вкладке Данные (Data) или Power Query:
После окна подтверждения увидим редактор запросов и нашу таблицу. Добавим пользовательский столбец на вкладке Добавить столбец (Add Column - Custom Column):
В появившемся окне введем имя столбца и формулу, которая создает список чисел от 1 до количества билетов в каждой строке:
После нажатия на ОК появится новый столбец со списками, элементы которых можно развернуть в строки, используя кнопку в шапке таблицы:
В итоге, получаем практически то, что хотелось:
Осталось удалить ненужный больше столбец Список (правой кнопкой мыши по заголовку - Удалить столбец) и выгрузить данные обратно на лист на вкладке Главная (Home) с помощью кнопки Закрыть и загрузить - Закрыть и загрузить в... (Close&Load - Close&Load to...) и указать подходящее место для результирующей таблицы:
И останется совсем простая часть - добавить к таблице столбец с формулой СЛУЧМЕЖДУ (RANDBETWEEN) для генерации случайных номеров билетов:
Особенно приятно, что при любых изменениях в исходной (левой) таблице (добавлении новых людей или изменении количества билетов), достаточно будет просто обновить правой кнопкой мыши нашу результирующую таблицу с номерами билетов.
P.S.
Если нужно, чтобы случайные числа не генерировались каждый раз заново при пересчете листа, а формировались один раз, сохраняя потом свои значения, то придется использовать макро-функцию StaticRandBetween из надстройки PLEX или что-то аналогичное.
Также можно, для наглядности, склеивать через дефис номер билета и порядковый номер из столбца Список прямо в Power Query, используя команду Объединить столбцы на вкладке Преобразование (Transform).
Ссылки по теме
- Слияние двух списков без дубликатов
- Извлечение уникальных элементов из диапазона
- Что такое макросы, как их использовать, куда вставлять код макросов на Visual Basic
При попытке запустить Power Query, выдает такую ошибку.
Details:
Microsoft.Mashup.Evaluator.Interface.ErrorException: Cannot create process. NativeErrorCode:5 ---> Microsoft.Mashup.Evaluator.Interface.ErrorException: Cannot create process. NativeErrorCode:5 ---> System.ComponentModel.Win32Exception: Cannot create process. NativeErrorCode:5
at Microsoft.Mashup.Evaluator.ContainerProcess.Start()
at Microsoft.Mashup.Evaluator.ContainerFactory.Container..ctor(String exePath, String exitMutexName, Int32 containerId, Int32 maxWorkingSetInMB)
at Microsoft.Mashup.Evaluator.ContainerFactory.CreateContainer()
at Microsoft.Mashup.Evaluator.ContainerPoolContainerFactory.CreateContainer()
at Microsoft.Mashup.Evaluator.RemoteEvaluationContainerFactory.CreateContainer()
at Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.CreateContainer()Power Query