Построить диаграмму по именнованной области

Тема в разделе "Visual Basic", создана пользователем wowa, 8 окт 2008.

  1. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Ка можно, не программно, построить диаграмму по именнованной области?

    Есть таблица
    A1:B5 , name = "www"
    Далее вручную строю диаграмму и прописываю в Data Range "=www"
    Все строиться как надо, но когда я проверяю Data Range, то уже там "$A$5:$B$5"
    Т.е. если я добавлю в таблицу еще одно значение, т.е. будет A1B6 (name все равно ="www"), то диаграмма не воспримет новое значение, т.к. она строиться по уже не по "www", а по "$A$5:$B$5"

    Подскажите, как выйти из данной ситуации??
     
  2. Tanya

    Tanya Гость

    В качетсве источника данных нужно указать диапазон с резервом для будущих данных, например "A1:B10000"
    (существует ограничение на количесвто данных, но это устанавливается опытным путем)))))).

    Такой подход позволяет добавлять новые данные и диаграмма будет автоматом изменяться!!!

    Можно проименовать диапазон и затем указать его в качестве источника данных для диаграммы, но потом в качестве данных все равно будет использоваться абсолютный адрес диапазона. К сожалению.
     
  3. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya , данный вариант не подходит, потому что на странице имеется две таблицы (например: А1:B5 и A11:B15 ) и две диаграммы
     
  4. Tanya

    Tanya Гость

    тогда (наверное) только программно
     
  5. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya , Подскажите, пожалуйста, как программно получить координаты сводной таблицы? или хотя бы ее верхний левый угол.. (
     
  6. Tanya

    Tanya Гость

    В примере рисуем прямоугольник над верхней левой ячейкой сводной таблицы:

    Код (Text):
    Sub MakeRectangle()
    Dim d As Range

    With ActiveWorkbook.ActiveSheet
    'получаем дипазон ячеек совдной таблицы
    Set d = .PivotTables(1).TableRange1

    'и рисуем прямоуголник над верхней левой ячейкой
    .AddShape msoShapeRectangle, d.Left, d.Top, d.Cells(1, 1).Width, d.Cells(1, 1).Height
    End With
    End Sub
     
  7. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya , подскажите пожалуйста, хоть и не по теме
    Есть массив значений, там текстовые значения
    Как из массива удалить повторяющиеся элементы???
     
  8. Tanya

    Tanya Гость

    Лучше по контексту смотреть )))
    Если массив одномерный и заполняешь сам, то удобно в коллекцию его загонять.
    А если массив уже существует, то тогда удобнее его отсортировать, а потом удалять повторы.
    Какой вариант предпочтительнее?
     
  9. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Ну вот небольшая выборка, массив одномерный, и заполняю сам. Вот как сделать , чтобы многие значения не повторялись. Неужто цикл в цикле делать... ((
     
  10. Tanya

    Tanya Гость

    Если заполняешь сам, тогда можно использовать коллекции!!!

    Код (Text):
    Sub Start()
    'Это стартовая функция, в ней заполняется коллекция
    Dim col As Collection
    Dim s As String

    Set col = New Collection

    'Заполенение
    AddItem col, "hh"
    AddItem col, "bb"
    AddItem col, "vvv"
    AddItem col, "hh"

    ' распечатываем колличество и коллекцию
    s = "Count = " & col.Count & vbCrLf          'количество

    'элементы
    For i = 1 To col.Count
    s = s & i & vbTab & col(i) & vbCrLf
    Next i

    ' выводим в окошке
    MsgBox s

    Set col = Nothing

    End Sub


    Sub AddItem(col As Collection, newElem As String)
    'добавление новых элементов в коллекцию
    'ошибка возникает, если такой элемент уже существует

    'поэтому здесь делаем игнор ошибок
    On Error Resume Next

    col.Add newElem, newElem

    'а здесь отключаем обработчик
    On Error GoTo 0
    End Sub
     
  11. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    ..

    Tanya , оуу, у мну наверно все же второй вариант, когда массив уже существует., сорри за некорректно заданный вопрос.
    Ну вообщем у меня в ячейке вот такая строка
    С помощью
    Я перевожу в массив, и теперь нужно удалить одинаковые элементы
     
  12. Tanya

    Tanya Гость

    Нуууу, тут такое дело ....
    Цикла не избежать никак, но если делать по второму варианту, то , как понимаешь
    циклов будет несколько, а если делать микс ))) первого и второго, то достаточно только одного цикла

    Есть вариант не использовать сплит, тоже будет один цикл...
    1) Вариант нескольких циклов без коллекций мне не нравится, потомучто писать дольше, отлаживаться сложнее, явных преимуществ я не вижу.
    2) Вариант только сплит + один цикл с коллекцией - проще всего.
    3) Вариант только цикл с коллекцией, что-то среднее: не нужно сортировать или несколько раз пробегать по исходной строке, но чуть сложнее ))) в разбиении самой строки на подстроки.

    Я опишу второй вариант (я бы сделала бы так)))), а если уж совсем не устроит так, то подумаем, как сделать первый вариант)))

    Код (Text):
    Sub n()
    Dim i As Integer
    Dim arr() As String
    Dim strSource As String
    Dim col As Collection

    strSource = "HTML::Object Pascal::SQL::Прочее::HTML::Object Pascal"
    arr = Split(strSource, "::")

    Set col = New Collection
    For i = LBound(arr) To UBound(arr)
    AddItem col, arr(i)
    Next i

    strSource = "Найдено " & col.Count & " элементов:" & vbCrLf
    For i = 1 To col.Count
    strSource = strSource & i & vbtcb & col(i) & vbCrLf
    Next i

    MsgBox strSource

    End Sub

    Sub AddItem(col As Collection, Item As String)
    On Error Resume Next

    col.Add Item, Item

    On Error GoTo 0
    End Sub
    В примере strSource можно передавать в функцию как параметр
     
  13. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya , Огромное спасибо, выручили! Вот только рейтинг пока поднять не могу (ограничение 7 дней)
     
  14. Tanya

    Tanya Гость

    Да, ладно :) рада помочь
     
  15. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya, возникло еще пару вопросов((, может знаете как их решить:
    1. На странице была одна сводная таблица, и я ее рефрешил так:
    Далее у меня срабатывало событие PivotTableUpdate - вообщем работало все как надо

    Теперь у меня на другой странице - 3 Сводной таблицы.
    Мне их нужно сразу три рефрешнуть, и только потом чтобы запускалось событие......
    Вот как это возможно сделать??... Либо что-то другое придумать...
    В PivotTableUpdate у меня по каждой сводной таблице строиться обычная таблица, далее по обычной - диаграмма.
     
  16. Tanya

    Tanya Гость

    Если идет принудительный рефреш 3 таблиц сразу, то можно заменить событие на обычную процедуру,
    которую и выполнять после принудительного рефреша. Событие убираем.
     
  17. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya , насколько я понял , то мне такой вариант не подходит,.. так как событие PivotTableUpdate должно существовать.., потому что при работе со сводной таблицей у меня перестраиваются другие таблицы и диаграммы!
     
  18. Tanya

    Tanya Гость

    То есть должно существовать событие, которое отключается при принудительном обновлении сразу трех таблиц,
    а в остальных случаях работает?
    Если так, то создаем новую процедуру, которая содержит функционал обработчика события,
    в событии просто вызываем эту процедуру.
    Далее создаем флаг на уровне модуля (или проекта, смотря как написаны макросы), который по умолчанию равен, например, False.
    Перед принудительном обновлением выставляем его в True, а после обновления таблиц вызываем процедуру и выставляем флаг снова в False.

    Схематически, выглядеть будет примерно так:
    Код (Text):
    ' Module
    Private blnRefreshOff as Boolean

    ...
    Sub AfterRefresh()
    ...
    End Sub

    Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
    If Not blnRefreshOff Then
    Call AfterRefresh
    End If
    End Sub

    ...

    Private Sub MyProc()
    ...
    blnRefreshOff = True

    Worksheets(WSName1).PivotTables(PTName1).PivotCache.Refresh
    Worksheets(WSName1).PivotTables(PTName2).PivotCache.Refresh
    Worksheets(WSName1).PivotTables(PTName3).PivotCache.Refresh

    Call AfterRefresh

    blnRefreshOff = False
    ...
    End Sub
     
  19. wowa

    wowa Well-Known Member

    Регистрация:
    1 фев 2007
    Сообщения:
    842
    Симпатии:
    0
    Tanya , подскажите еще такой момент
    Делаю сортировку такой таблицы, первый столбик - номер строки
    с помощью кода:
    Получаю как надо, отсортировал первый столбик по году
    Но не получается отсортировать вот такую таблицу:

    Вообщем когда отсортировать не строки(как в первом случае), а столбики
     
  20. Tanya

    Tanya Гость

    На скорую руку, не пробуя: в справке говорится что у метода Sort есть параметр Orientation

    может это именно то, что нужно?
     
Загрузка...

Поделиться этой страницей