|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Hello world! Если хочу создать функцию, которая будет возвращать диапазон, я могу указать Тип Range после списка параметров. Например так: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9.
Но как быть если ф-ция должна возвращать одномерный массив строк. Как правильно указать этот тип и нужно ли вообще его указывать? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 18:51 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Попробовал сделать так: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Но получаю такую ошибку: ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 18:53 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Если убрать выделенный Set, функция отрабатывает без ошибки. Подскажите когда нужно указывать оператор Set ? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 18:55 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Когда идет присвоение ссылки на объект. В данном случае переменной типа Variant присваивается массив, это допустимое присвоение ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 19:16 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Shocker.Pro, А как избавиться от variant, и задать функцию нужного мне типа(массив строк) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 19:42 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2А как избавиться от variantзачем? как раз Variant и используется для возврата массива (если я правильно помню) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 19:50 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Shocker.Pro, Для понятности и однообразности кода. Или это в принципе не возможно? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 19:56 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2, мда... возможно,конечно. у функции есть тип возвращаемого значения. раз вы его не объявляете явно, он оказывается Variant. Примите к сведению, что отвечать на такие не есть хорошо. Чем бы себя ни оправдывали. А как насчет того, чтобы ждать и быть готовым читать такие ответы - решайте сами. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2018, 21:48 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2, Код: vbnet 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.05.2018, 09:42 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Казанский, Спасибо!) ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 15:20 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
boobyYagrus2, мда... возможно,конечно. у функции есть тип возвращаемого значения. раз вы его не объявляете явно, он оказывается Variant. Примите к сведению, что отвечать на такие не есть хорошо. Чем бы себя ни оправдывали. Извените, но я не смог монять почему у вас такая реакция. Или вы считаете, что не стоит заморачиваться с объявлением возвращаемого типа значения, при описании функции? Поясните пожалуйста... ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 15:26 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2, в данном конкретном случае все нормально. Но в общем случае есть обратная сторона: даже если в массив попадут числовые значения - они будут преобразованы в текст. Да и вообще любые значения будут преобразованы в текст. Если объявите функцию As Long, а внутри в массив попытаетесь записать текст - получите ошибку. Это стоит учитывать. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 15:39 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Задумался над тем что присваивается и малость завис... Как тогда объяснить такой маневр Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
До выполнения последней строчки процедуры M(), массив ArrColName не имеет размера. Наверное у него есть только адрес. Если бы не скобки перед равно ArrColName () = F_ColName(WSheet, iColMax, iColMin), то было бы логично, что происходит присвоение ссылки(указателя/адреса) на массив, возвращаемый функцией F_ColName Возможно я заморачиваюсь, но присвоение без цикла одного массива другому для меня непонятно. Если вас не затруднит, прошу высказать ваши соображения, по моему вопросу. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 15:46 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2...но я не смог монять почему у вас такая реакция. ... нет у меня никакой реакции. вы задали легкий вопрос на знакомство с синтаксисом. для его решения достаточно открыть справку на синтаксис определения функции. Ну, хотя бы, для приличия сделать это. А потом задавать вопрос, если не смогли что-то понять. Yagrus2До выполнения последней строчки процедуры M(), массив ArrColName не имеет размера. Наверное у него есть только адрес. нет. и адреса массива тоже нет. Он равен нулю. Есть переменная, в которой будет хранится впоследствии массив уже известно какого типа, но еще неизвестно, какого размера. Это называется объявлением динамического массива. Да, конечно у этой переменной есть адрес. Но это не тот адрес, о котором вы подумали. Yagrus2Если бы не скобки перед равно ArrColName() = F_ColName(WSheet, iColMax, iColMin), скобки перед равно здесь необязательны. Yagrus2то было бы логично, что происходит присвоение ссылки(указателя/адреса) на массив, возвращаемый функцией F_ColName VBA работает не так. Присвоение значения массиву путем использования знака равенства приводит к созданию нового экземпляра массива соответствующего размера и копирования в него значений из массива в левой части выражения. Таким образом, в вашем коде два копирования одного и того же массива. первый раз в строке Код: vbnet 1.
а второй раз в строке Код: vbnet 1.
используя процедуру вместо функции вы могли бы избежать создания двух копий массива. пример работы с динамическими массивами: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38.
PS я легко понимаю монять , но от извените предлагаю избавиться. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 17:59 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
booby, авториз массива в левой части выражения. это опечатка из массива в правой части выражения, конечно. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 18:02 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
boobyТаким образом, в вашем коде два копирования одного и того же массива. первый раз в строке Код: vbnet 1.
а второй раз в строке Код: vbnet 1.
А вот и нет! Поставьте точку останова на строке F_ColName = ColNameToFormulas() и смотрите в Locals. До этой команды F_ColName имеет тип String(), т.е. неинициализированный массив, а ColNameToFormulas имеет тип String(0 To 10) - массив, содержащий значения. Определите в Immediate адрес содержимого первого элемента массива Код: vbnet 1. 2.
Выполните команду - F8. Теперь F_ColName имеет тип String(0 To 10), а ColNameToFormulas имеет тип String()! То есть при присвоении была переписана именно ссылка на структуру SAFEARRAY, а не весь буфер строк. Теперь еще раз F8 - возвращаемся в процедуру и определяем адрес содержимого первого элемента массива ArrColName Код: vbnet 1. 2.
Адрес тот же! Значит, опять была присвоена ссылка, а буфер остался на месте. VBA конечно не самый прогрессивный язык программирования, но кое-что в нем сделано правильно ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 19:44 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Казанский, ok. возврат из функций оптимизирован. копирования нет. я ошибся в своей памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 20:20 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
boobyКазанский, ok. возврат из функций оптимизирован. копирования нет. я ошибся в своей памяти. что тоже неправда в качестве универсального утверждения. (между прочим, strptr здесь вообще не может использоваться в качестве доказательства. Из неизменности ссылки на строку в элементе массива не следует, что массив не копировался) правильно получается как-то так - возврат массива оптимизирован, если он целиком создается внутри функции (возвращаемый массив не был передан в качестве входного параметра). на поиграться: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.05.2018, 20:48 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
boobyчто тоже неправда в качестве универсального утверждения. (между прочим, strptr здесь вообще не может использоваться в качестве доказательства. Из неизменности ссылки на строку в элементе массива не следует, что массив не копировался)Проведя ряд экспериментов обнаружил, что для строковой ячейки массива ф-ции VarPtr и StrPtr дают разные значения адреса. Для обычной строковой переменной ситуация аналогичная. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
VarPtr() StrPtr()VarPtr &f(0)=109391576 StrPtr &f(0)=108808580VarPtr &sVar=3075664 StrPtr &sVar=108809260 Для меня это непонятная странность НОМЕР 1 boobyправильно получается как-то так - возврат массива оптимизирован, если он целиком создается внутри функции (возвращаемый массив не был передан в качестве входного параметра). на поиграться: Поработав с вашими скриптами заметил: Пусть массив создается внутри функции, а затем присваивается самой функции. Тип ф-ции и массива совпадают После того, как функция отработала, результат ее работы присваивается массиву без размера во внешней процедуре. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
До выполнения строки Код: vbnet 1.
Expression Typef1 Long()ffLong(0 to 2)А после ее выполненияExpression Typef1 Long(0 to 2)ff Long() Для меня обмен типами это загадка. Странность НОМЕР 2 Если бы была возможность получать адрес на каждом этапе выполнения кода, тогда бы можно было рассуждать дальше. Получить адрес ф-ции f1 ни до ее инициализации, ни после у меня не получается. Что касается присвоения Код: vbnet 1.
то здесь также не представляется возможным проверить, как происходит трансформация массива(изменение его размера и наполнение). Хотя Адреса ff и m1 совпадают. booby Соглашусь с вами, что вариант с процедурой однозначно не делает дополнительных операций. И еще мое соображение по поводу вашего скрипта: так как массивы m0, m1, m2 объявлены во внешней процедуре, а m0 получает адрес внутри ф-ции f2 - все они получается обычным копированием. А так же никакого "обмена типами" не происходит ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2018, 15:54 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2, VarPtr(sVar) - адрес переменной sVar StrPtr(sVar) - адрес начала самой строки строки. Есть строковая переменная sVar. ее адрес показывает VarPtr В этой переменной хранится адрес, по которому физически размещена сама строка. Этот адрес показывает strptr 2) это не "обмен типами". Так вообще-то не говорят не применительно ни к какой ситуации в VBA. И мы не будем пока искусственно придумывать новые смыслы. массив - специальная конструкция. Она полностью определяется типом хранимого в ячейке элемента, количеством размерностей, указанием номера начального элемента - счет элементов с нуля или с единицы и максимальным значением индекса по каждой размерности - 1 (число элементов в размерности). Статический массив полностью специфицирован в момент своего объявления. Динамический массив может объявляться только указанием типа хранимого элемента. и должен в том смысле, что тип считается обязательным к объявлению. В VBA все не указанные явно типы оказываются Variant. В Variant можно запихнуть значение любого типа, включая и объект и массив. для массива m() VarPtr(m) - адрес переменной m по этому адресу хранится структура, описывающая массив - тип его элемента, количество размерности и т.п. и т.д.смотри выше. В той структуре есть и адрес начала области данных, выделенной под элементы массива. Но. VarPtr(m(5)) - это адрес элемента массива с индексом 5. И можно сказать следующее: Если VarPtr(m(5) = VarPtr(n(5)) то, несомненно, пятые элементы обоих массивов лежат в одной и той же области памяти, начинаются с одного и того же адреса. А если нужно получить именно адрес начала области памяти, выделенной под массив, то запрашивать это надо так: VarPtr(m(0)) Если в массиве хранятся строки, то в каждой ячейке массива, на самом деле, хранится адрес начала соответствующей строки. И адрес области памяти, начиная с которого лежат символы именно этой строки получается так StrPtr(m(5)) Функция. Про функции можно знать следующее: Имя функции - это просто переменная внутри ее кода, свободная для произвольного использования Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Но. Есть большое но для функций, возвращающих массив. так как обращение к массиву происходит помощью круглых скобок, и рекурсивный вызов функции с параметрами тоже происходит с использованием круглых скобок, дизайнеры языка запретили прямое манипулирование с именем функции как ее внутренней переменной, в случае, когда функция возвращает массив. По части присвоения массивов через знак равенства. И для строк и для массивов , если m и n - переменные, то m = n в качестве выражения присваивания всегда означает, что происходит копирование. Строки или массива. Я забыл о том, что в случае, когда n - функция, и созданный в ней объект, массив в обсуждаемом случае, не имел и не может иметь других переменных за пределами кода этой функции, хранящих ссылку на него, то копирования можно безопасно избежать. Что VBA и делает. А чтобы получить копирование, можно даже не передавать в функцию аргумент типа массива. Должно быть достаточно, например, манипуляции с глобально определенным массивом. Тогда его возврат обязан, по здравому смыслу, приводить к копированию. автортогда бы можно было рассуждать дальше Стоп-стоп. Что бы это не значило, я не обещал и продолжаю не обещать что-либо рассуждать. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2018, 17:31 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
boobyдля массива m() VarPtr(m) - адрес переменной m по этому адресу хранится структура, описывающая массив.... здесь тоже некая неточность. по этому адресу хранится адрес структуры, описывающей массив... и далее по тексту. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2018, 18:01 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Прошу прощение, не мог ответить раньше... 1.boobyЕсть большое но для функций, возвращающих массив. дизайнеры языка запретили прямое манипулирование с именем функции как ее внутренней переменной, в случае, когда функция возвращает массив.То есть, мы не можем получить адрес такой внутренней переменной? 2.boobyЯ забыл о том, что в случае, когда n - функция, и созданный в ней объект, массив в обсуждаемом случае, не имел и не может иметь других переменных за пределами кода этой функции, хранящих ссылку на него, то копирования можно безопасно избежать. Что VBA и делает. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Если вы про этот случай, то как это проверить? Неужели достаточно равенство VarPtr &ff(0) и VarPtr &m1(0)? 3. Про присвоение массивов Пусть m1, f1 - массивы. m1 = f1 и m1() = f1() - эквивалентные записи? 4. Про структуру, которая хранит метаданные массива Можно ли получить ее адрес? Такой код не работает Код: vbnet 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 16:35 |
|
EXCEL Определение функции возвращаюшей одномерный массив строк
|
|||
---|---|---|---|
#18+
Yagrus2, по последнему вопросу Код: vbnet 1. 2. 3. 4. 5.
остальное поищи по форуму смотри здесь, в ветке visual basic и в ветке Microsoft Access искать можно как-то так, например http://www.sql.ru/forum/afsearch.aspx?s=varptrarray&bid=46 ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2018, 16:48 |
|
|
start [/forum/topic.php?fid=61&msg=39644584&tid=2172313]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
58ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 176ms |
0 / 0 |