WedX - журнал о программировании и компьютерных науках

Сложная многоколоночная и многострочная конкатенация в Excel с использованием vba

Я создаю электронную таблицу, полную продуктов для интернет-магазина, и мне действительно нужна помощь в одном из полей.

У меня есть родительский продукт с несколькими дочерними продуктами (например, футболки разных размеров и цветов).

Для простоты давайте поработаем с двумя цветами (красный и синий) и двумя размерами (маленький и большой) — это дает 4 возможных различных комбинации продукта (например, маленький красный, маленький синий, большой красный и большой синий).

Эти данные перечислены на моем листе следующим образом:

sku          colour      size       price
t-shirt-rs   red         small      0
t-shirt-rl   red         large      2
t-shirt-bs   blue        small      0
t-shirt-bl   blue        large      2

В настоящее время; вот сложная часть - в строке родительского продукта мне нужно объединить все вышеуказанные данные в одну ячейку следующим образом:

"t-shirt-rs[red#small[0;t-shirt-rl[red#large[2;t-shirt-bs[blue#small[0;t-shirt-bl[blue#large[2"

«[» отделяет каждое новое название дочернего продукта (sku) от его опций, а «#» отделяет опции дочернего продукта, затем следует еще один «[», чтобы отделить корректировку цены, а затем «;» между каждым дочерним продуктом

Вышесказанное вообще имеет смысл??

1-й родительский продукт, который я должен загрузить, имеет 4 варианта (размер, цвет, мотив и материал), и каждый вариант имеет до 9 вариантов (4 размера, 9 цветов, 6 мотивов и 2 материала). Думаю, я смотрю на (4x9x6x2=) 432 дочерних продукта, которые сделают очень длинную ручную конкатенацию.

Я мог бы сделать простой =A2 & "[" & B2 & "#" & C2..... в нужной мне ячейке, но я боюсь, что это займет вечность.

Я надеюсь, что смогу перечислить дочерние продукты, как указано выше (с большим количеством копирования и вставки: o), а затем использовать vba для объединения в одну ячейку и добавления [, # и; во всех нужных местах.

Я полагаю что-то вроде:

with the first row
(add " symbol?) & 1st cell & "[" & 2nd cell & "#" & 3rd cell & "#" & 4th cell .....
move down one row
same as above
keep going until I run out of child products??
add final " symbol

Я новичок в VBA, поэтому не знаю, с чего начать. Может ли кто-нибудь указать мне в правильном направлении?

Спасибо, Алан

24.04.2014

  • Почему бы не сделать вашу первоначальную идею =A2 & "[" & B2 & "#" & C2 & "#" & D2 в столбце E, затем перетащить его вниз, а затем объединить весь столбец E? 25.04.2014
  • Итак, если столбец E становится: "t-shirt-rs[red#small#football#denim[0;, как мне объединить весь столбец E? 25.04.2014
  • На самом деле, я опубликую решение сейчас.... 25.04.2014
  • Вы гений сэр!! Однако еще один вопрос: формула заканчивается =concatenate("t-shirt......, поэтому содержимое ячейки равно t-shirt....., как я могу сделать содержимое ячейки равным "t-shirt... с добавленной кавычкой в ​​начале и конце (это как-то связано с одинарными и двойными кавычками?) 25.04.2014
  • @AlanEnglefield в формуле Excel вы можете добавить кавычки как "" внутри кавычек, так что само по себе это будет """" & rest & """" 25.04.2014
  • Я обновил свое решение последней частью... Надеюсь, это имеет смысл... 25.04.2014
  • Спасибо всем, но, учитывая мое ограниченное знакомство с vba, я думаю, что буду придерживаться решения с перетаскиванием, лол: о) 25.04.2014

Ответы:


1

Исходя из комментариев, я бы сделал это следующим образом:

В ячейке E2:

= A2 & "[" & B2 & "#" & C2 & "#" & D2

В ячейке F2:

= F1 & E2

(это предполагает, что F1 пусто)

Затем перетащите E2 и F2 вниз на длину ваших данных. Ваше окончательное значение будет значением в последней строке, ячейке F.

Надеюсь, это имеет смысл.

ОБНОВЛЕНИЕ:

Теперь вы знаете, что ваше окончательное значение — это последняя ячейка в столбце F, но вам нужно окружить ее ", поэтому в ячейку, в которую вы хотите получить окончательное решение, введите следующую формулу:

="""" & OFFSET(F2,COUNTA(F2:F100000)-1,0) & """"

Это найдет последнее значение в столбце F и заключит его в необходимые кавычки.

24.04.2014
  • +1 за креативность и предоставление ответа, который сможет использовать ОП. 25.04.2014
  • спасибо, @ckuhn203 - я думаю, мы оба знаем, что VBA, вероятно, является лучшим решением в этом случае (следовательно, ваше решение великолепно), но, учитывая его комментарии о VBA, я пытался помочь ему избежать этого, насколько это возможно :) 25.04.2014
  • Ух ты! Так просто, но так идеально. Даже проще, чем в комментариях выше. Я думаю, что я слишком усложнил это в своей голове. Спасибо Джон 25.04.2014
  • :) С удовольствием - рад, что помогло! 25.04.2014
  • Я должен добавить для полноты картины, что у меня возникли проблемы; в названиях моих продуктов были тире, а = F1 & E2 выше только подбирал часть до и включая первый тире во 2-й ячейке до самого низа. Я решил это, изменив форматирование столбца с «Общее» на «Текст». 25.04.2014
  • @john bustos Я фанат простоты. Как программисты, мы, вероятно, иногда слишком быстро начинаем писать код. Чистая красота. Опять таки. Престижность. 25.04.2014

  • 2

    попробуйте что-то вроде. Я комментирую то, что он делает.

       'Children either refers to a range or a 2-d array
    Function GetDescriptor(children) As String
        Dim descriptor As String
        Dim i As Long
        Dim arr
    
        'query if a range
        If TypeOf children Is Range Then
            'a) single cell range returns a scalar and b) doesn't make sense here anyway
            If children.Areas(1).Count = 1 Then Exit Function
            'load the data into an array (quicker than looping through cells)
            arr = children.Value
        End If
    
        'loop through the data
        For i = LBound(arr, 1) To UBound(arr, 1)
            'join the row's data together as specified
            descriptor = descriptor & _
                arr(i, LBound(arr, 2)) & "[" & _
                arr(i, LBound(arr, 2) + 1) & "#" & _
                arr(i, LBound(arr, 2) + 2) & "[" & _
                arr(i, LBound(arr, 2) + 3) & _
                IIf(i < UBound(arr, 1), ";", "")
        Next i
    
        'return wrapped in "
        GetDescriptor = """" & descriptor & """"
    
    End Function
    
    24.04.2014
  • Ааааааааааааа. Мне потребовалась секунда, чтобы понять это. Продолжение строки сбило меня с толку. Очень хорошо. 25.04.2014
  • @ckuhn203 да, я часто заставляю свои функции обрабатывать как диапазоны, так и массивы, поэтому я могу повторно использовать их в коде и формулах по мере необходимости - просто нужно разобраться с множеством ужасных LBounds - будь проклят тот день, когда были разрешены как основание 0, так и основание 1;) ( и позор, что в VBA нет перегрузки метода для типа параметра) 25.04.2014
  • Хотел бы я дать этому еще +1. Это так же поэтично, как и vba. 28.04.2014

  • 3

    Вам нужно будет перебрать каждый столбец в каждой строке. Каждый столбец должен обрабатываться по-разному, потому что для каждого из них требуется свой разделитель. Код ниже должен помочь вам начать. Вам нужно будет исследовать функции, чтобы вы могли фактически возвращать значение, а также функции для возврата последней использованной строки. Это довольно жестко закодировано, но это должно помочь вам начать.

    Sub myConcat()
        Dim ws As Worksheet
        Set ws = ThisWorkbook.Sheets("Sheet1") ' change to appropriate sheet
    
        Dim col As Long ' keeps track of what column we're on
        Dim row As Long ' keeps track of what row we're on
    
        Dim str As String 'stores string as we build it across the columns
        Dim finalstring As String ' stores string as we build it across rows; this will be our     final return value
    
        For row = 2 To 5 'change 5 to last row that needs processed
            For col = 1 To 4 ' number of colums with data
                Select Case col
                    Case 1
                        str = Cells(row, col).Value
                    Case 2
                        str = str & "[" & Cells(row, col).Value
                    Case 3
                        str = str & "#" & Cells(row, col).Value
                    Case 4
                        str = str & "[" & Cells(row, col).Value & ";"
                End Select
                'Debug.Print str
            Next col
            finalstring = finalstring & str
            Debug.Print finalstring
        Next row
    
    End Sub
    
    24.04.2014
  • просто следите за трейлингом ; по последнему пункту. В остальном выглядит хорошо. 25.04.2014
  • Хороший улов. Спасибо @Cor_Blimey. Однако я не собираюсь обновлять свой ответ. Во всяком случае, мне больше нравится ответ Джона. 25.04.2014
  • действительно, формулы - это путь к простоте, если это возможно;) 25.04.2014
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]