Страницы: 1
RSS
Оптимизация работы через VBA: замена формул или использовать данные СТ?
 
Хочу посоветоваться, как применить решение через VBA в задаче, где есть исходные данные, которые необходимо разбить по контрагентам и суммировать по продуктам. На данный момент сущ-ет 2 способа: созданы два листа (есть разбивка по продуктам), на которых прописаны формулы СУММ(ЕСЛИ( и 2-й способ - Свод.Таб., результат одинаков, но в последней не устраивает формат таблицы. Решение через VBA будет предполагать замену формулы или позволит использовать данные СТ для создания удобного формата таблицы?  
VBA только входит в мой обиход, поэтому хотелось бы понять от чего отталкиваться. Пока только удалось записать макрос по созданию СТ и прикрепить его к кнопке на листе =)  
 
Заранее выражаю безмерную благодарность за ответ.
 
кинь xls
 
{quote}{login=Марчук}{date=14.01.2009 01:26}{thema=}{post}кинь xls{/post}{/quote}
 
продолжаю свою тему - пытаясь продвинуться в построении данных, полученных с помощью сводной таблицы, был записан макрос, однако когда он был прикреплен к кнопке, стала выпадать ошибка в первой строке куска:  
   Range("B3").Select  
   With ActiveSheet.PivotTables("ÑâîäíàÿÒàáëèöà2").DataPivotField  
       .Orientation = xlColumnField  
       .Position = 1  
   End With  
С чем это связано мне понять не удается, поэтому интересно ваше мнение =)  
 
Попутно, хочу поинтересоваться - как можно разнести значения полученной таблицы на два листа (с соответствующими именами), если кто-то не захочет работать со сводной таблицей?
 
Не могу понять, по Ф8 иногда эту строку прохожу и таблица строится, но по кнопке...  
Run-time error "1004"    
и пишет недопустимом имени поля таблицы...  
 
Set PT = PTCache.CreatePivotTable(TableDestination:=pvtSht.Range("A4"), TableName:="СводнаяТаблица2")
 
Благодарю за отклик!  
Однако макрос у меня не срабатывает ни через F8, ни через кнопку, т.к. возникает ошибка Run-time '7' Out of memory и отправляет на строку:  
pvtSht.Name = "OtchetPivot"
 
Не знаю почему, но в Вашей книге многое что "должно" работать - не работает.  
К сожалению не знаю где там и что порыто. Сам рока по букварю и рекордеру.  
Может кто зайдет, сумеет подсказать из-за чего ошибки...
 
{quote}{login=Branch}{date=14.01.2009 11:50}{thema=Оптимизация работы через VBA: замена формул или использовать данные СТ?}{post}Хочу посоветоваться, как применить решение через VBA в задаче, где есть исходные данные, которые необходимо разбить по контрагентам и суммировать по продуктам. На данный момент сущ-ет 2 способа: созданы два листа (есть разбивка по продуктам), на которых прописаны формулы СУММ(ЕСЛИ( и 2-й способ - Свод.Таб., результат одинаков, но в последней не устраивает формат таблицы. Решение через VBA будет предполагать замену формулы или позволит использовать данные СТ для создания удобного формата таблицы?  
VBA только входит в мой обиход, поэтому хотелось бы понять от чего отталкиваться. Пока только удалось записать макрос по созданию СТ и прикрепить его к кнопке на листе =)  
 
Заранее выражаю безмерную благодарность за ответ.{/post}{/quote}  
 
Вы в макросе захватываете диапазон, в котором есть пустые столбы.  
Без заголовков. Это косяк.  
У вас: ..."'Кол-во счетов всего'!R4C1:R2687C26... - а надо "'Кол-во счетов всего'!R4C1:R2687C15...  
Разница только в последних двух цифрах.  
Глубже не вникал.
 
Друзья, я не оставляю надежды разобраться что к чему в предложенной версии кода от Igor67, но пока вопрос возник несколько в другом - в приложенном сейчас файле код работает, суть в том, что сводная опущена на несколько строк, в пустые строки приходится вручную добавлять таблицу - значения общих итогов СТ(чтобы не фильтровали сводную по клиентам). Как вписать построение этой таблицы в код? =)
 
пардонмуа, файл забыл
 
За позицию сводной на листе отвечает pvtSht.Range("A9") в строке...    
Set PT = PTCache.CreatePivotTable(TableDestination:=pvtSht.Range("A9"), TableName:="СводнаяТаблица1")  
Вроде теперь работает, но почему по Вашему файлу необходимы селекты и активаты?  
Понять не могу, добавил явное указание листов и начало работать (наверное).  
Попробуйте.
 
Проверьте в начале кода где WorksheetFunction.CountA диапазон ячеек.  
По моему забыл внести коррективы, а так как у Вас есть данные на листе для сводной и их не надо очищать, то укажите номер ячейки ниже А6.  
У меня с А1-?  
Вечером посмотрю в файле, если необходимо.  
Игорь67
 
о! работает - там где нужно было - исправила диапазоны  
спасибо, Igor67, за то что показал немного уличной магии =)  
 
единственное, код несколько разросся после того, как туда добавилось рисование таблицы и вставка в нее значений, поэтому интересно, можно ли сделать обобщение для выделения полужирным названия строк/столбцов и покороче написать расчерчивание таблицы? [вообще интересен подход, который лежит в основе таких упрощений]
 
оффтоп:  
кстати, еще понравилась ладошка, которая появляется при наведении на кнопку - у меня так не было, моя кнопка создана через панель Visual Basic + исходный текст - как сделать, чтобы появлялась ладошка?
 
Начну снизу, меню Вид Панели инструментов и выбираете Формы.  
Вставляете кнопку и после щелчка правой кнопкой мыши появится возможность назначить кнопке макрос, изменить текст или просто изменить размер/переместить кнопку.  
Можно на любую автофигуру назначать макрос.  
Смотрите пример....
 
Igor67, у меня только с Вами в этой теме завязался плодотворный диалог [отдельная благодарность за 'ладошку'], поэтому делюсь новостями.
 
Засада - процедура выполнения обрывается, упорно выводя в сводной по столбцу АКТИВНЫЕ_СЧЕТА количество по полю.    
На добавление третьей строкой .Function = xlSum в кусок    
 
With PT.DataPivotField  
      .Orientation = xlColumnField  
      .Position = 1  
End With  
 
реакции не последовало.    
Конечно интересно, как это можно использовать в будущем - в одной сводной над разными полями выполнять разные операции (в одном сумма, в другом количество, в третьем произведение), НО сейчас это вообще не кстати. Куда вписать xlSum ?  
 
Если у кого-то ещё есть версии, предлагаю ими смело делиться =)
 
Branch, Вы меня все время ставите в тупик.  
Весь макрос не выполняется или только не правильно выполняется действие над данными в АКТИВНЫЕ_СЧЕТА - считает количество по полю, а Вам надо сумму?  
Будет Время попробую найти решение. Это моя 3 сводная, и вся с приключениями...
 
Проверил, у меня в файле все поля данных на сумме. Зайдите в параметры поля. Может вам просто изменить подпись /имя поля?
 
{quote}{login=Igor67}{date=24.01.2009 01:46}{thema=}{post}Проверил, у меня в файле все поля данных на сумме. Зайдите в параметры поля. Может вам просто изменить подпись /имя поля?{/post}{/quote}  
Имя поля изменяется при выборе операции, т.е. если выполняется операция количество, имя поля = количество по полю ...  
У меня макрос выполяется до момента, когда появляется Количество по полю АКТИВНЫЕ_СЧЕТА, после чего выходит Run-time '1004' Невозможно получить свойство PivotFields класса PivotTable, строка ошибки:  
.PivotFields("Сумма по полю АКТИВНЫЕ_СЧЕТА").Caption = "Количество активных СКС"  
Если вручную выбрать в параметрах поля операцию Сумма, имя поля соответственно меняется, и после нажатия Ф5 макрос успешно срабатывает.  
 
Вся описанная ситуация и заставила меня задаться вопросом - где прописывается операция (сумма, количество и пр.), которую необходимо выполнить в сводной над конкретным полем.
 
Скажу честно - прочитал 2 раза, ни чего не понял.  
Как можно поменять поля в макросе? Вы его запустили и все что в нем прописано будет, ну или наверно будет, сделано.  
В данном варианте все поля данных - операция сумма. Изменения/выбора программно нет. В чем у Вас проблема? Менять имя автоматически формируемое Ехс в данном коде не предусмотрено.
 
{quote}{login=Igor67}{date=28.01.2009 10:15}{thema=}{post}Скажу честно - прочитал 2 раза, ни чего не понял.  
Как можно поменять поля в макросе? Вы его запустили и все что в нем прописано будет, ну или наверно будет, сделано.  
В данном варианте все поля данных - операция сумма. Изменения/выбора программно нет. В чем у Вас проблема? Менять имя автоматически формируемое Ехс в данном коде не предусмотрено.{/post}{/quote}  
 
Я затрудняюсь определить причину, по которой в сводной таблице (строящейся макросом) именно в поле АКТИВНЫЕ_СЧЕТА выводится количество, а не сумма. Поэтому хотелось бы обойти прерывание на ручное изменение операции над этим полем за счет указаний в коде операций.
 
With PT  
 
With .PivotFields("Сумма по полю СЧЕТОВ_ВСЕГО")  
.Caption = "Общее количество СКС"  
.Function = xlSum  
End With  
 
.PivotFields("Сумма по полю АКТИВНЫЕ_СЧЕТА").Caption = "Количество активных СКС"  
 
 
попробуй так вставить сумму
 
Может выглядит неказисто, но "количеству по полю" больше меня не терроризирует...  
 
Set PT = PTCache.CreatePivotTable(TableDestination:=pvtSht.Range("A9"), TableName:="СводнаяТаблица1")  
     
 
   With pvtSht.PivotTables("СводнаяТаблица1").PivotFields("КОМПАНИЯ")  
       .Orientation = xlRowField  
       .Position = 1  
   End With  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("СЧЕТОВ_ВСЕГО"), "Общее количество СКС", _  
       xlSum  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("АКТИВНЫЕ_СЧЕТА"), _  
       "Количество активных СКС", xlSum  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("ЛИМИТЫ (руб)"), "ЛИМИТЫ (сумма в рублях)", _  
       xlSum  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("УСТАНОВЛЕННЫЕ"), "Установленные лимиты (количество)" _  
       , xlSum  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("ПЕРЕУСТАНОВЛЕННЫЕ"), "Переустановленные лимиты (количество)" _  
       , xlSum  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("ЗАКРЫТЫЕ_ЛИМИТЫ"), "Закрытые лимиты (количество)" _  
       , xlSum  
   pvtSht.PivotTables("СводнаяТаблица1").AddDataField pvtSht.PivotTables _  
       ("СводнаяТаблица1").PivotFields("ДЕЙСТВУЮЩИЕ_ЛИМИТЫ"), _  
       "Действующие лимиты (количество)", xlSum  
   With pvtSht.PivotTables("СводнаяТаблица1").DataPivotField  
       .Orientation = xlColumnField  
       .Position = 1  
   End With  
       
   With pvtSht.PivotTables("СводнаяТаблица1").PivotFields("КЛИЕНТЫ")  
       .Orientation = xlPageField  
       .Position = 1  
   End With  
     
   'End With  
     
           
   With PT.DataPivotField  
       .Orientation = xlColumnField  
       .Position = 1  
   End With
 
Я честно не видел ошибки. Когда входишь в свойства поля - показывало операцию СУММ(). Как это происходило в Вашем файле - для меня тайна...
 
Igor67, для меня все это вообще П[олтергейст] полный..
Вот еще один прикол, - использую образец кода для построения СТ в других файлах, в двух всё ровно, в 3-й никак...  
Option Explicit  
 
Sub SVOD()  
Dim bazaWb As Workbook 'текущая книга (общий файл)  
Dim bazaSht As Worksheet 'лист Baza в общем файле  
Dim pvtSht As Worksheet  'лист для сводной в общем файле  
Dim PTCache As PivotCache 'переменная для записи исходных данных сводной табл  
Dim PT As PivotTable      'переменная сводной табл  
Dim myCountA As Integer  
Dim myPvtRng As Range  
 
 
       Set bazaWb = ThisWorkbook  
       Set bazaSht = bazaWb.Sheets("valbal")  
   'On Error Resume Next  
     
   With Application  
       .ScreenUpdating = False  
       .DisplayAlerts = False  
       .Calculation = xlManual  
         
           If Not SheetExit("Итоги") Then  
              Set pvtSht = Sheets.Add  
              pvtSht.Name = "Итоги"  
           Else: Set pvtSht = bazaWb.Sheets("Итоги")  
           End If  
         
       myCountA = Excel.WorksheetFunction.CountA(pvtSht.Range("A1:A2000"))  
       'очищаем лист с данными сводной таблицы  
       If myCountA > 0 Then  
           With pvtSht  
               .Range(.Cells(1, 1), .Cells(bazaSht.Cells(Rows.Count, 1).End(xlUp).Row, .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, Columns.Count).End(xlToLeft).Column)).Cells.Clear  
           End With  
       End If  
         
   'создаем кэш для сводной таблицы с ячейки А1 до правой нижней в таблице  
  ' Set myPvtRng = bazaSht.Range(bazaSht.Cells(1, 1), bazaSht.Cells(bazaSht.Cells(Rows.Count, 1).End(xlUp).Row, bazaSht.Cells(bazaSht.Cells(Rows.Count, 1).End(xlUp).Row, Columns.Count).End(xlToLeft).Column))  
  ' bazaSht.Activate  
  ' Debug.Print myPvtRng.Address  
     
 '  Set PTCache = ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _  
  '   SourceData:=myPvtRng.Address)  
   
     
     
     
   Set PTCache = ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _  
     SourceData:=Sheets("valbal").Range("A2").CurrentRegion.Address) 'можно явно указывать расположение исходных данных  
       
     
       
       
   Set PT = PTCache.CreatePivotTable(TableDestination:=pvtSht.Range("A2"), TableName:="СводнаяТаблица1")  
     
   With PT 'создаем саму сводную таблицу  
       .PivotFields("Код вал.").Orientation = xlColumnField  
       .PivotFields("Продукт").Orientation = xlRowField  
       .PivotFields("Входящий (КП)").Orientation = xlDataField  
       .PivotFields("Оборот (ДП)").Orientation = xlDataField  
               
   End With  
                 
   With PT.DataPivotField  
       .Orientation = xlColumnField  
       .Position = 1  
   End With  
     
   pvtSht.Activate  
     
       With PT  
          .PivotFields("Сумма по полю Входящий (КП)").Caption = "Входящий оборот"  
           .PivotFields("Сумма по полю Оборот (ДП)").Caption = "Оборот по К-ту"  
  End With  
                         
             
       'включаем все, что отключали  
       .Calculation = xlAutomatic  
       .DisplayAlerts = True  
       .ScreenUpdating = False  
   End With  
 
End Sub  
 
Private Function SheetExit(iSheet As String)  
   On Error Resume Next  
   With Sheets(iSheet): End With  
   SheetExit = (Err = 0)  
End Function  
 
 
 
С ошибкой Application-defined or object-defined error справиться я не могу.
 
ох-ох-ох, в чем ошибка была так и не удалось выяснить, по тернистым путем удалось обойти  
 
Возник другой вопрос - как прописать в макросе группировку?  
Макрорекодер выдает такое чудо:Range("B5:C5,E5:J5").Select  
   Range("E5").Activate  
   Selection.Group  
   ActiveWindow.ScrollColumn = 4  
   ActiveWindow.ScrollColumn = 3  
   ActiveWindow.ScrollColumn = 2  
   ActiveWindow.ScrollColumn = 1  
   Range("B5").Select  
   ActiveSheet.PivotTables("СводнаяТаблица1").PivotFields("Код вал.2").PivotItems( _  
       "Группа1").Caption = "Валюта в рублях"  
   Range("B5").Select  
   ActiveSheet.PivotTables("СводнаяТаблица1").PivotFields("Код вал.2").PivotItems( _  
       "Валюта в рублях").ShowDetail = False  
 
после чего выплывает снова ошибка Application-defined or object-defined error !
 
Для наглядности прилагаю файл. В данный момент задача однозначно решается с помощью СТ (база данных на листе valbal), однако на листе TOTAL показан вид таблицы, которая используется для отчетов. Отсюда появляет несколько вопросов:  
1. Если работать дальше с СТ, как наглядно представить данные, т.е. сделать группировку "Валюта в рублях" макросом (сейчас он строит только сводную)  
2. Если работать с привычной таблицой (TOTAL), как заполнить её значениями из СТ (с учетом все той же группировки, т.е. суммы) ?  
 
Пожааалуйста, присоединитесь к моей проблеме =)
 
Branch, видел Ваш пост...  
Пока нет времени, самому надо еще учиться со сводными, да и вообще с ВБА...  
На форум захожу только "почитать"... К вечеру голова забита тараканьими ножками, а с утра опять работа. Кризис однако?!  
Может Вы нову тему начнете? Когда 1 вопрос - 1 тема, то чаще отвечают..
Страницы: 1
Читают тему
Наверх