Модераторы: mihanik
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с Range, Получить область определенных ячеек 
:(
    Опции темы
Elfix
Дата 13.10.2009, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Добрый день!

Как получить Range определенных ячеек (не диапазона, например, A1, A5, A10, A102) и записать их результат в Range?
Я пробовал получить список ячеек в строку str и передавать ее в функцию Range. Все работает, но если у меня очень много отдельных ячеек (больше 100 тыс), то строки не хватает и программа вылетает (кажется ограничение в 255 символов).

Мой код привожу ниже.

Код

Sub dgs()
    
    Dim MyRange As Range ' Сюда надо сохранить Range с ячейками, у которых высота больше 0
    Set MyRange = Selection ' Получаю выделенный диапазон
    
    Dim str As String ' В строку буду записывать адреса ячеек, у которых Height > 0
    str = ""
    
    For Each Data In MyRange.Rows
        If Data.Height > 0 Then
            If Len(str) > 0 Then
                str = str + ","
            End If
            str = str + Data.Address
        End If
    Next
    
    ' Получаю Range с нужными ячейками и записываю в переменную MyRange
    Set MyRange = Range(str)
    
End Sub

PM MAIL   Вверх
motorway
Дата 13.10.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 578
Регистрация: 2.3.2008

Репутация: нет
Всего: 0



А зачем записывать это в Range? Что с этим дальше будет делаться?
Может, можно записывать в несколько строк? Или временные ячейки?
PM MAIL   Вверх
Akina
Дата 13.10.2009, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Бред какой-то...
1) переменная Data не определена
2) перебираешь ты не ячейки, а строки (кстати, непонятно, откуда может взяться 100 тыс. строк)

Цитата(Elfix @  13.10.2009,  17:48 Найти цитируемый пост)
кажется ограничение в 255 символов

254. И обойти его не получится.

Добавлено через 1 минуту и 48 секунд
А в чём вообще смысл сего действия?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Elfix
Дата 13.10.2009, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Цитата("motorway")

А зачем записывать это в Range? Что с этим дальше будет делаться?

Это необходимо. Мне нужен Range чтобы работать со значениями ячеек и их коррдинатами на листе. Дальнейший код (который я не публиковал) работает как раз с переменной типа Range. Однако в самом Range находятся не совсем корректные данные.

Цитата("Akina")

1) переменная Data не определена

В некоторых случаях в VBA можно не объявлять переменную перед ее использованием. А объявлять временную переменную внутри цикла For Each вообще не приемлемо для меня и неэтично для некоторых программистов.

Цикл кстати корректно работает. Если бы ты завел это в редактор и запустил, я думаю вопросов бы у тебя в этой части кода не возникало бы.
Цитата("Akina")

2) перебираешь ты не ячейки, а строки (кстати, непонятно, откуда может взяться 100 тыс. строк)

Я перебираю строки области данных, которые содержат в себе помимо значений еще и координаты на листе и важные для меня параметры.
100 тыс. строк это не предел для организации, занимающейся коммерческой деятельностью. В нашей организации, если тебе интересно, в Excel выгружают данные из БД для анализа. Моя задача дать инструмент для более удобной работы с данными.

Цитата("Akina")

А в чём вообще смысл сего действия? 

Смысл провести ABC-анализ по тем значениям ячеек, которые выделены пользователем и которые не скрыты (например автофильтром) и помещение результатов работы справа от выделенной области. Все это кстати, я уже реализовал. Осталось только заполнить корректно начальный Range с которым работает мой скрипт.

Добавлено @ 18:58
Наверно я не совсем хорошо сформулировал вопрос.

Код

Set myRange = Range("A1,A8,A30,A80,A120,A600,A3400");

Идеальный для меня вариант создания и сохранения Range, но строка, которая передается как параметр в Range() имеет ограничение на количество символов, а значит для меня не подходит. Ищу подобный способ создания Range.

Это сообщение отредактировал(а) Elfix - 13.10.2009, 18:58
PM MAIL   Вверх
Akina
Дата 13.10.2009, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Elfix @  13.10.2009,  19:49 Найти цитируемый пост)
Если бы ты завел это в редактор и запустил, я думаю вопросов бы у тебя в этой части кода не возникало бы.

Завёл и запустил. Но для меня Option Explicit - строка обязательная и неприкасаемая.

Цитата(Elfix @  13.10.2009,  19:49 Найти цитируемый пост)
100 тыс. строк это не предел 

Чем ёрничать, лучше бы сразу указал, что у тебя 2007 офис.

Цитата(Elfix @  13.10.2009,  19:49 Найти цитируемый пост)
Идеальный для меня вариант создания и сохранения Range, но строка, которая передается как параметр в Range() имеет ограничение на количество символов, а значит для меня не подходит. Ищу подобный способ создания Range.

Не понимаю, что тебе мешает сохранять и передавать эту строку? 
Другой вариант - клонировать текущий Selection во временный Range (это у тебя сделано), снять выделение, а потом подходящие ячейки ВКЛЮЧАТЬ В Selection. В результате по окончании цикла проверки ты будешь иметь на листе MultiSelection - а по сути нужный тебе Range. Который ты и клонируешь в переменную. Потом, если надо, восстановишь старое выделение.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Elfix
Дата 13.10.2009, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Цитата

снять выделение, а потом подходящие ячейки ВКЛЮЧАТЬ В Selection.

Чтобы не быть голословным не мог бы ты предоставить кусочек кода? Тогда я думаю, вопросов у меня не возникнет.
Я нашел подходящий для себя способ, но он мне не очень нравится. Интересно было бы узнать другие методы. Конкретно, тот, который ты предложил, на первый взгляд он разумен. Но пока не знаю как это технически реализовать. Не поделишься кодом?

Добавлено через 1 минуту и 28 секунд
Цитата

Не понимаю, что тебе мешает сохранять и передавать эту строку? 

Мешает ограничение на количество символов в строке. Если их тьма, то строка просто не вмещает в себя весь размер необходимых для моей работы ячеек.
PM MAIL   Вверх
Akina
Дата 13.10.2009, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Elfix @  13.10.2009,  22:03 Найти цитируемый пост)
Чтобы не быть голословным не мог бы ты предоставить кусочек кода? Тогда я думаю, вопросов у меня не возникнет.

Вот ещё! сам сделаешь...

Сервис - Макрос - Начать запись.
Выдели два несмежных диапазона.
Сервис - Макрос - Остановить запись.
Сервис - Макрос - Макросы - свежесозданный макрос - Изменить.

И изучай.

Цитата(Elfix @  13.10.2009,  22:03 Найти цитируемый пост)
Мешает ограничение на количество символов в строке. 

Ограничение на длину СТРОКИ вовсе не такое, как на длину аргумента функции Range().


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Elfix
Дата 13.10.2009, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Цитата

Вот ещё! сам сделаешь...

Так и думал. Пустой треп и ни слова по делу. Подобный флуд вы развели в теме по T-SQL. Советы, усмешки, оскорбления, но ни строчки кода или примера. Создается впечатление что вы некомпетентны во многих вопросах, но все равно стараетесь вставить свое веское слово. Вы зачастую даже не понимаете сути вопроса, но продолжаете давать бесценные советы. "Слышу звон, но не знаю где он" (с).

Цитата

Сервис - Макрос - Начать запись.
Выдели два несмежных диапазона.
Сервис - Макрос - Остановить запись.
Сервис - Макрос - Макросы - свежесозданный макрос - Изменить.

Если бы проблема решалась таким образом, то я бы не стал задавать вопрос здесь. Два несмежных диапазона вполне умещаются в строке str. Проблема заключалась как раз в том, что при выборе нескольких сотен тысяч таких несмежных диапазонов строка обрезается и ее невозможно становится передать в Range() чтобы получить ожидаемый результат.

Цитата

Ограничение на длину СТРОКИ вовсе не такое, как на длину аргумента функции Range(). 

Тем не менее, аргументом функции Range() является строка. И если ее размер ограничен, то становится невозможным передать нужное количество несмежных диапазонов в функцию Range().


И все таки я решил проблему через функцию Union(). Пока не протестил ее на корректность, но на первый взгляд мой подход оказался удачным. Мое решение привожу в листинге снизу:
Код

Sub dgs()
    
    Dim MyRange As Range
    Dim TempRange As Range
    
    Set MyRange = Selection
    Set TempRange = Range(MyRange.Rows(1).Address)
    
    For Each Data In MyRange.Rows
        If Data.Height > 0 Then
            Set TempRange = Union(TempRange, Range(Data.Address))
        End If
    Next
    
    Set MyRange = TempRange
    
End Sub

PM MAIL   Вверх
Akina
Дата 13.10.2009, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Elfix @  13.10.2009,  23:53 Найти цитируемый пост)
Если бы проблема решалась таким образом, то я бы не стал задавать вопрос здесь. 

Если бы ты вместо того, чтобы выпендриваться, проделал сказанное - то почти сразу увидел бы использование функции Union в полученном тексте макроса при выделении несмежных диапазонов. Да, пришлось бы чуть-чуть поработать руками и мозгами - но тебе это недоступно. Ты способен только получить готовое решение, а когда тебе показывают путь - ты воспринимаешь это как флуд, насмешку, оскорбление... и только после того как понимаешь, что за готовеньким надо было идти в "центр помощи" - начинаешь наконец думать. А с этого надо начинать, а не оставлять напоследок.

Цитата(Elfix @  13.10.2009,  23:53 Найти цитируемый пост)
Тем не менее, аргументом функции Range() является строка. И если ее размер ограничен, то становится невозможным передать нужное количество несмежных диапазонов в функцию Range().

О господи! Повторяю ещё раз.
Максимальная длина переменной типа String (содержимого, а не имени - так, на всякий случай) составляет сотни мегабайт (как написано в хелпе - ограничего доступной памятью).
Функция Range в одном из вариантов принимает в качестве аргумента тип String - но с дополнительным ограничением. Не более 254 байта. Это ограничение интерфейса Range, а не типа String.
Поэтому ты мог в качестве варианта решения передавать не Range, а именно String, и уже в месте потребления парсить его на отдельные адреса.



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Elfix
Дата 14.10.2009, 07:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 167
Регистрация: 13.7.2005

Репутация: нет
Всего: нет



Всё-таки немного некорректный код. Переделал, если кому интересно:
Код

Sub ssdy()
    
    Dim MyRange As Range
    Dim TempRange As Range
    
    Set MyRange = Selection
    
    For Each Data In MyRange.Rows
        If Data.Height > 0 Then
            If TempRange Is Nothing Then
                Set TempRange = Range(Data.Address)
            Else
                Set TempRange = Union(TempRange, Range(Data.Address))
            End If
        End If
    Next
    
    Set MyRange = TempRange

End Sub

PM MAIL   Вверх
Akina
Дата 14.10.2009, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Любопытно, почему 
Код

            If TempRange Is Nothing Then
                Set TempRange = Range(Data.Address)
            Else
                Set TempRange = Union(TempRange, Range(Data.Address))
            End If

а не 
Код

            If TempRange Is Nothing Then
                Set TempRange = Data
            Else
                Set TempRange = Union(TempRange, Data)
            End If
?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование, связанное с MS Office"
mihanik staruha

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами



  • Несанкционированная реклама на форуме запрещена
  • Пожалуйста, давайте своим темам осмысленный, информативный заголовок. Вопль "Помогите!" таковым не является.
  • Чем полнее и яснее Вы изложите проблему, тем быстрее мы её решим.
  • Оставляйте свои записи в "Книге отзывов о работе администрации"
  • А вот тут лежит FAQ нашего подраздела


Если Вам понравилась атмосфера форума, заходите к нам чаще!
С уважением mihanik и staruha.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование, связанное с MS Office | Следующая тема »


 




[ Время генерации скрипта: 0.0561 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.