Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - VBA

Страница: 1 |

 

  Вопрос: Range и Rows, вопрос по использованию. Добавлено: 17.11.08 13:24  

Автор вопроса:  Somes
Добрые сутки, уважаемые. Подскажите начинающему, почему, к примеру, работает:
Sub Cells()
Dim sStr
Dim oRange
Set oRange = Range(Cells(1, 1), Cells(1, 5))
For Each sStr In oRange
MsgBox sStr.Cells.Value
Next
End Sub


Но не работает:
Sub Cells()
Dim sStr
Dim oRange
Set oRange = Application.Rows(1)
For Each sStr In oRange
MsgBox sStr.Cells.Value
Next
End Sub


В документации сказанно, что Application.Rows(1) возвращает экземпляр Range, почему же тогда вторая конструкция не работает?

Ответить

  Ответы Всего ответов: 10  

Номер ответа: 1
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #1
Добавлено: 17.11.08 13:48
  1. Sub Cells()
  2. Dim sStr
  3. Dim oRange
  4. Set oRange = Range(Cells(1, 1), Cells(1, 5))
  5. For Each sStr In oRange
  6. MsgBox sStr.Cells.Value
  7. Next
  8. End Sub


У меня не работает также - сам проверял.

Это.. а скажи тогда ты мне: зачем тебе объявлять переменные и не указывать тип?

Почему ты забываешь в конце процедуры ставить
  1. Set oRange = Nothing
?

Ответить

Номер ответа: 2
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #2
Добавлено: 17.11.08 13:51
Да, забыл ответить на твой вопрос: потому что в выражении
  1. For Each sStr In oRange

является oRange не перечислением, а объектом Range

Ответить

Номер ответа: 3
Автор ответа:
 Somes



Вопросов: 3
Ответов: 7
 Профиль | | #3 Добавлено: 17.11.08 14:25
Да я как бы просто предоставляю vba самостоятельно выбрать тип. Если я правильно понимаю суть.
Я дико извиняюсь, Sub Cells() следует читать как Sub Что-угодно().

Ответить

Номер ответа: 4
Автор ответа:
 Nytrogen



Вопросов: 18
Ответов: 186
 Профиль | | #4 Добавлено: 17.11.08 15:50
Somes:
Да я как бы просто предоставляю vba самостоятельно выбрать тип

Если тип не указан явно, то независимо от содержимого переменной, она получает тип Variant.

Как вариант неработающей процедуры:
  1. Sub OutputRowValues()
  2.   Dim sStr As Variant
  3.   Dim oRange As Range
  4.   Set oRange = Range(Application.Rows(1).Address)
  5.   For Each sStr In oRange
  6.     MsgBox sStr.Value
  7.   Next
  8. End Sub


sStr.Cells писать излишне, ибо это возвращает то же самое, что и aStr: они оба ссылаются на один и тот же объект Range.


mc-black:
Почему ты забываешь в конце процедуры ставить Set oRange = Nothing?

Жизнь локальных переменных заканчивается после окончания процедуры, не так ли?

Ответить

Номер ответа: 5
Автор ответа:
 Somes



Вопросов: 3
Ответов: 7
 Профиль | | #5 Добавлено: 17.11.08 16:46
Nytrogen Большое спасибо за разъяснение.

И, извиняюсь, небольшой вопрос в догонку так сказать:
  1. Dim sStr As String 'Не суть принципиально, можно и Variant
  2. sStr = ActiveSheet.Cells(1, 1)
  3. MsgBox ActiveSheet.Cells(1, 1).Address 'Работает
  4. MsgBox sStr.Address 'Не работает


С чем это связано? .Address возращает значение типа string, что мешает работать второй конструкции?

Ответить

Номер ответа: 6
Автор ответа:
 Nytrogen



Вопросов: 18
Ответов: 186
 Профиль | | #6 Добавлено: 17.11.08 18:11
Вы сами не понимаете, что пишите. Вы объявляете переменную sStr типа String, а потом присваиваете ей ссылку на диапазон. Что туда по-вашему будет записано? Неизвестно.

Далее, строка sStr = ActiveSheet.Cells(1, 1) по сути означает, что Вы в переменную sStr пытаетесь записать объект ячейки. Это неправильно хотя бы потому, что это не позволит Вам сделать сам интерпретатор VBA, не говоря о трудоёмкости данного процесса. Ссылкам на объекты, так называемым объектным переменным, присваивать значение можно только используя оператор Set, т.е. правильной записью является следующая:
  1. Set sStr = ActiveSheet.Cells(1, 1)

Тип объектных переменных должен быть естественно объектным (никаких стрингов), в Вашем случае - это Range (более общим вариантом является Object и на худой конец - Variant). Помните, что чем точнее Вы укажете тип, тем меньше ресурсов будет пожирать Ваш макрос. Таким образом, правильный код выглядит следующим образом:
  1. Sub Test()
  2.   Dim sStr As Range 'Только объектный тип!!!
  3.   Set sStr = ActiveSheet.Cells(1, 1)
  4.   MsgBox ActiveSheet.Cells(1, 1).Address 'Работает
  5.   MsgBox sStr.Address 'Теперь и это работает
  6. End Sub

Ответить

Номер ответа: 7
Автор ответа:
 Somes



Вопросов: 3
Ответов: 7
 Профиль | | #7 Добавлено: 17.11.08 19:08
Nytrogen Большое спасибо Вам за разъяснения.

Ответить

Номер ответа: 8
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #8
Добавлено: 18.11.08 10:42
Nytrogen
Жизнь локальных переменных заканчивается после окончания процедуры, не так ли?

Сам экземпляр объекта - это не переменная. Объектная переменная VBA - это что-то вроде указателя или дескриптора (точно не знаю) на экземпляр объекта в памяти. При корректном завершении процедуры стек локальных переменных разрушается. VB при этом автоматически освобождает память, занятую под экземпляры объектов. Но сборщик мусора не всегда может отработать как положено (например при возниконовении ошибки в коде процедуры с вылетом из нее с ошибкой), поэтому рекомендуется всегда явным образом освобождать объекты. Описанное мной, пусть может и не абсолютно точно, называется утечкой памяти.

Ответить

Номер ответа: 9
Автор ответа:
 Nytrogen



Вопросов: 18
Ответов: 186
 Профиль | | #9 Добавлено: 18.11.08 12:55
mc-black #8:
Означает ли это, что создаваемые объекты так же надо удалять Delete'ом?

Ответить

Номер ответа: 10
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #10
Добавлено: 19.11.08 09:55
  1. Set Object = Nothing
достаточно. Можно и забыть про это, но лучше не забывать.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам