Страницы: 1
RSS
Преобразовать горизонтальную таблицу в вертикальную
 
Приветствую Форумчане и Хозяева Сайта!
С прошедшими праздниками всех!

Есть следующая задача:
Продажи в рублях, по дням, несколько десятков номенклатуры по нескольким городам за год.
Таблица получается большая. Она в горизонтальном виде. Её нужно преобразовать в вертикальный. В виде базы данных.
Во вложении пример.

Буду очень благодарен за решение без макросов и надстроек.
 
Цитата
vlad_d написал: без макросов и надстроек.
Примените макрос ОДИН раз из ЭТОГО приема
Изменено: Sanja - 10.01.2019 14:07:27
Согласие есть продукт при полном непротивлении сторон
 
vlad_d,

Поскольку начиная с Excel 2016 Power Query уже не надстройка, то вот  :) :
Код
let
    Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"№", "Город", "Номенклатура", "ИТОГО"}, "Дата", "Рубли"),
    #"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"ИТОГО"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Removed Columns",{{"Дата", type date}, {"Рубли", type number}, {"№", Int64.Type}, {"Город", type text}, {"Номенклатура", type text}})
in
    #"Changed Type"
 
Вариант формулами
 
Sanja, благодарю Вас!
Способ работает. Сохраню себе макрос.

Aleksei_Zhigulin, спасибо за ответ!
Я "чайник" в Power Query). Сходу не разобрался, как это сделать... Проверю на работоспособность чуть позже.

jakim , и Вам благодарность!!!
Это уже ближе и более понятнее. Быстрее смогу вникнуть.

Если еще будут варианты с удовольствием приму их!
 
Добрый день!
У меня похожая задача, но не пойму как применить данные методы, помогите пожалуйста
 
Виктор, здравствуйте
Метод .IndentLevel (например Range("A1").IndentLevel или Cells(1,1).IndentLevel) вернёт уровень отступов в ячейке — по ним (отступам), вы и сможете создать классическую плоскую структуру — вот вам набор инструментов  ;)
Изменено: Jack Famous - 06.09.2021 14:42:27
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Код
Option Explicit

Sub ВертикальнуюВгоризонтальную()
    Dim sh As Worksheet
    Set sh = Sheets(1)
    
    Dim y As Long
    Dim arrA As Variant
    Dim arr2 As Variant
    With sh
        y = .Cells(.Rows.Count, 1).End(xlUp).Row
        arrA = .Range(.Cells(1, 1), .Cells(y, 1))
        y = .Cells(2, .Columns.Count).End(xlToLeft).Column
        arr2 = .Range(.Cells(2, 1), .Cells(3, y))
    End With
    
    Dim cl As Range
    Dim rn As Range
    On Error Resume Next
        Set rn = sh.UsedRange.Offset(4, 7).SpecialCells(xlCellTypeConstants)
    On Error GoTo 0
    If Not rn Is Nothing Then
        Dim arrO As Variant
        ReDim arrO(1 To rn.Cells.Count, 1 To 7)
        
        Dim u As Long
        Dim x As Integer
        u = 0
        For Each cl In rn
            With cl
                If Not IsEmpty(.Value) Then
                    u = u + 1
                    For y = .Row To 1 Step -1
                        Select Case sh.Cells(y, 1).IndentLevel
                        Case 0
                            arrO(u, 1) = arrA(y, 1)
                            Exit For
                        Case 2
                            arrO(u, 2) = arrA(y, 1)
                        Case 6
                            arrO(u, 3) = arrA(y, 1)
                        Case 8
                            If IsEmpty(arrO(u, 4)) Then
                                arrO(u, 4) = arrA(y, 1)
                            End If
                        End Select
                    Next
                    arrO(u, 5) = arr2(1, .Column)
                    arrO(u, 6) = arr2(2, .Column)
                    arrO(u, 7) = .Value
                    
                End If
            End With
        Next
        Sheets(2).Cells(1, 1).Resize(UBound(arrO, 1), UBound(arrO, 2)) = arrO
    End If
    
End Sub
Если, конечно, не отвергать макросы.
 
Как работать с этим макросом
 
Создание макросов и пользовательских функций на VBA (planetaexcel.ru)
Способа 1, в принципе, достаточно.

Вставьте код в стандартный модуль из сообщения #8.
Запустите макрос, Alt+F8 Выполнить.
Результат будет на втором листе.
 
Не получается выходит ошибка, я думал что то из-за не формата выгрузки из 1С (добавляются пустые столбцы), но нет все равно выходит одна и та же ошибка
 
Попробовал запускать из файла с поддержкой макросов, вставлял в отдельный модуль все равно ошибка
 
Кликните Debug.
И выложите скриншот, где код остановился.
 
Вот где остановился
 
Файл отличается от файла из примера.
Добавьте второй лист.
 
:)
Цитата
vlad_d написал: Буду очень благодарен за решение без макросов
Цитата
vlad_d написал:  Sanja , благодарю Вас! Способ работает. Сохраню себе макрос.
Изменено: vikttur - 08.09.2021 17:21:51
 
Offtopic: видимо, пришлось сохранить макрос без благодарности - с отвращением :)
 
Цитата
МатросНаЗебре написал: Файл отличается от файла из примера.
Не загружается - большой размер
Отправил на почту
 
Цитата
МатросНаЗебре написал:
Файл отличается от файла из примера.Добавьте второй лист.
Вот ссылка https://docs.google.com/spreadsheets/d/13EMyDv0AsOHHOqozTXZXzsd5ohC1Yv7b/edit?usp=sharing&ou...
 
МатросНаЗебре просил Вас отправлять на почту?
Пример - небольшая демонстрация вопроса, а не рабочий файл.
 
Поправил на случай, если нет второго листа.
Код
Option Explicit
 
Sub ВертикальнуюВгоризонтальную()
    Dim sh As Worksheet
    Set sh = Sheets(1)
     
    Dim y As Long
    Dim arrA As Variant
    Dim arr2 As Variant
    With sh
        y = .Cells(.Rows.Count, 1).End(xlUp).Row
        arrA = .Range(.Cells(1, 1), .Cells(y, 1))
        y = .Cells(2, .Columns.Count).End(xlToLeft).Column
        arr2 = .Range(.Cells(2, 1), .Cells(3, y))
    End With
     
    Dim cl As Range
    Dim rn As Range
    On Error Resume Next
        Set rn = sh.UsedRange.Offset(4, 7).SpecialCells(xlCellTypeConstants)
    On Error GoTo 0
    If Not rn Is Nothing Then
        Dim arrO As Variant
        ReDim arrO(1 To rn.Cells.Count, 1 To 7)
         
        Dim u As Long
        Dim x As Integer
        u = 0
        For Each cl In rn
            With cl
                If Not IsEmpty(.Value) Then
                    u = u + 1
                    For y = .Row To 1 Step -1
                        Select Case sh.Cells(y, 1).IndentLevel
                        Case 0
                            arrO(u, 1) = arrA(y, 1)
                            Exit For
                        Case 2
                            arrO(u, 2) = arrA(y, 1)
                        Case 6
                            arrO(u, 3) = arrA(y, 1)
                        Case 8
                            If IsEmpty(arrO(u, 4)) Then
                                arrO(u, 4) = arrA(y, 1)
                            End If
                        End Select
                    Next
                    arrO(u, 5) = arr2(1, .Column)
                    arrO(u, 6) = arr2(2, .Column)
                    arrO(u, 7) = .Value
                     
                End If
            End With
        Next
        
        If Sheets.Count < 2 Then Sheets.Add After:=Sheets(1)
        
        Sheets(2).Cells(1, 1).Resize(UBound(arrO, 1), UBound(arrO, 2)) = arrO
    End If
     
End Sub
 
...
Изменено: vikttur - 09.09.2021 22:34:41
 
Продолжаю гадать по скриншотам )
Код
Option Explicit
  
Sub ВертикальнуюВгоризонтальную()
    Dim sh As Worksheet
    Set sh = Sheets(1)
      
    Dim y As Long
    Dim arrA As Variant
    Dim arr2 As Variant
    With sh
        y = .Cells(.Rows.Count, 1).End(xlUp).Row
        arrA = .Range(.Cells(1, 1), .Cells(y, 1))
        'y = .Cells(2, .Columns.Count).End(xlToLeft).Column
        y = .UsedRange.Column + .UsedRange.Columns.Count - 1
        arr2 = .Range(.Cells(2, 1), .Cells(3, y))
    End With
      
    Dim cl As Range
    Dim rn As Range
    On Error Resume Next
        Set rn = sh.UsedRange.Offset(4, 7).SpecialCells(xlCellTypeConstants)
    On Error GoTo 0
    If Not rn Is Nothing Then
        Dim arrO As Variant
        ReDim arrO(1 To rn.Cells.Count, 1 To 7)
          
        Dim u As Long
        Dim x As Integer
        u = 0
        For Each cl In rn
            With cl
                If Not IsEmpty(.Value) Then
                    u = u + 1
                    For y = .Row To 1 Step -1
                        Select Case sh.Cells(y, 1).IndentLevel
                        Case 0
                            arrO(u, 1) = arrA(y, 1)
                            Exit For
                        Case 2
                            arrO(u, 2) = arrA(y, 1)
                        Case 6
                            arrO(u, 3) = arrA(y, 1)
                        Case 8
                            If IsEmpty(arrO(u, 4)) Then
                                arrO(u, 4) = arrA(y, 1)
                            End If
                        End Select
                    Next
                    arrO(u, 5) = arr2(1, .Column)
                    arrO(u, 6) = arr2(2, .Column)
                    arrO(u, 7) = .Value
                      
                End If
            End With
        Next
         
        If Sheets.Count < 2 Then Sheets.Add After:=Sheets(1)
         
        Sheets(2).Cells(1, 1).Resize(UBound(arrO, 1), UBound(arrO, 2)) = arrO
        Sheets(2).Select
    End If
End Sub
Страницы: 1
Наверх