Содержание
- Чтение и запись значения ячейки в VBA
- Обращение к конкретной ячейке
- Чтение значения из ячейки
- Запись значения в ячейку
- Различие между использованием .text и .value в VBA Access
- 5 ответов
- Vba excel value или text
- Distinction between using .text and .value in VBA Access
- 5 Answers 5
Чтение и запись значения ячейки в VBA
В приложении Excel все данные как правило находятся в ячейках на листах, с которыми макросы работают как с базой данных. Поэтому, начинающему программисту VBA важно понимать как читать значения из ячейки Excel в переменные или массивы и, наоборот, записывать какие-либо значения на лист в ячейки.
Обращение к конкретной ячейке
Прежде чем читать или записывать значение в ячейке, нужно определиться с тем, как можно указать какая именно ячейка нам необходима.
Полный путь к ячейке A1 в Книге1 на Листе1 можно записать двумя вариантами:
- С помощью Range
- С помощью Cells
Пример 1: Обратиться к ячейке A3 находящейся в Книге1 на Листе1
Однако, как правило, полный путь редко используется, т.к. макрос работает с Книгой, в которой он записан и часто на активном листе. Поэтому путь к ячейке можно сократить и написать просто:
Пример 2: Обратиться к ячейке A1 в текущей книге на активном листе
Если всё же путь к книге или листу необходим, но не хочется его писать при каждом обращении к ячейкам, можно использовать конструкцию With End With. При этом, обращаясь к ячейкам, необходимо использовать в начале «.» (точку).
Пример 3: Обратиться к ячейке A1 и B1 в Книге1 на Листе2.
Так же, можно обратиться и к активной (выбранной в данный момент времени) ячейке.
Пример 4: Обратиться к активной ячейке на Листе3 текущей книги.
Чтение значения из ячейки
Есть 3 способа получения значения ячейки, каждый из которых имеет свои особенности:
- Value2 — базовое значение ячейки, т.е. как оно хранится в самом Excel-е. В связи с чем, например, дата будет прочтена как число от 1 до 2958466, а время будет прочитано как дробное число. Value2 — самый быстрый способ чтения значения, т.к. не происходит никаких преобразований.
- Value — значение ячейки, приведенное к типу ячейки. Если ячейка хранит дату, будет приведено к типу Date. Если ячейка отформатирована как валюта, будет преобразована к типу Currency (в связи с чем, знаки с 5-го и далее будут усечены).
- Text — визуальное отображение значения ячейки. Например, если ячейка, содержит дату в виде «число месяц прописью год», то Text (в отличие от Value и Value2) именно в таком виде и вернет значение. Использовать Text нужно осторожно, т.к., если, например, значение не входит в ячейку и отображается в виде «#####» то Text вернет вам не само значение, а эти самые «решетки».
По-умолчанию, если при обращении к ячейке не указывать способ чтения значения, то используется способ Value.
Пример 5: В ячейке A1 активного листа находится дата 01.03.2018. Для ячейки выбран формат «14 марта 2001 г.». Необходимо прочитать значение ячейки всеми перечисленными выше способами и отобразить в диалоговом окне.
Пример 6: В ячейке С1 активного листа находится значение 123,456789. Для ячейки выбран формат «Денежный» с 3 десятичными знаками. Необходимо прочитать значение ячейки всеми перечисленными выше способами и отобразить в диалоговом окне.
При присвоении значения переменной или элементу массива, необходимо учитывать тип переменной. Например, если оператором Dim задан тип Integer, а в ячейке находится текст, при выполнении произойдет ошибка «Type mismatch». Как определить тип значения в ячейке, рассказано в следующей статье.
Пример 7: В ячейке B1 активного листа находится текст. Прочитать значение ячейки в переменную.
Таким образом, разница между Text, Value и Value2 в способе получения значения. Очевидно, что Value2 наиболее предпочтителен, но при преобразовании даты в текст (например, чтобы показать значение пользователю), нужно использовать функцию Format.
Запись значения в ячейку
Осуществить запись значения в ячейку можно 2 способами: с помощью Value и Value2. Использование Text для записи значения не возможно, т.к. это свойство только для чтения.
Пример 8: Записать в ячейку A1 активного листа значение 123,45
Все три строки запишут в A1 одно и то же значение.
Пример 9: Записать в ячейку A2 активного листа дату 1 марта 2018 года
В данном примере тоже запишется одно и то же значение в ячейку A2 активного листа.
Визуальное отображение значения на экране будет зависеть от того, какой формат ячейки выбран на листе.
Источник
Различие между использованием .text и .value в VBA Access
Я передаю значения textbox1.text в запрос, а иногда и в строку:
Как мне узнать, когда мне следует поставить combor1 = comboReason1.Value ?
Кроме того, почему мне нужно установить фокус для элемента управления, чтобы он ссылался на его свойство? Для меня это не имеет смысла.
Кроме того, когда я устанавливаю combor4 = comboReason4.Value , а .value имеет значение null, я получаю сообщение об ошибке недопустимого использования null.
5 ответов
- «.text» дает вам то, что отображается на экране
- «.value» дает вам базовое значение
Оба обычно дают одинаковый результат, за исключением случаев, когда соответствующий элемент управления
- элемент управления combobox или listbox
- отображаемое значение отличается от связанного столбца
- id_Person — это элемент управления combobox в форме
- источник строки — «SELECT id_Person, personName FROM Tbl_Person»
- ширина столбца: «0 см; 3 см».
- связанный столбец равен 1
В этой ситуации:
- id_Person.text отображает Tbl_Person.personName
- id_Person.value отображает Tbl_Person.id_Person.
Свойство .text доступно только в том случае, если соответствующий элемент управления находится в фокусе.
.text — строковое значение, поэтому оно не может быть Null, а .value может быть Null
РЕДАКТИРОВАТЬ: .text можно вызвать только тогда, когда элемент управления имеет фокус, а .value можно вызвать в любое время .
Вы можете использовать свойство Text , чтобы установить или вернуть текст, содержащийся в текстовом поле или в части текстового поля в поле со списком.
Чтобы установить или вернуть свойство Text элемента управления, элемент управления должен иметь фокус , в противном случае возникает ошибка. Чтобы переместить фокус на элемент управления, вы можете использовать метод SetFocus или действие GoToControl.
Вы можете использовать свойство Value , чтобы определить или указать, выбран ли элемент управления, выбранное значение или параметр в элементе управления, текст, содержащийся в элементе управления текстовым полем, или значение настраиваемого свойства.
Свойство Value возвращает или задает свойство элемента управления по умолчанию, которое предполагается, когда вы явно не указываете имя свойства. В следующем примере, поскольку значением по умолчанию для текстового поля является значение свойства Text, вы можете ссылаться на его настройку свойства Text без явного указания имени свойства.
.text запускает проверку поля и вызывает ошибку, если проверка поля нарушена. .value не запускает проверку поля, вы можете ввести ЛЮБОЕ значение
Эта ветка и ответы здесь хорошо объясняют проблему. Я хотел бы добавить пару дополнительных моментов, которые я обнаружил экспериментально:
Порядок приоритета свойств:
Из того, что я видел в Access 2007, если .ControlSource не определено при открытии формы, .Value будет Null .
Если вы установите для свойства .ControlSource значение =»» (пустая строка), это приведет к тому, что свойство .Value будет иметь значение по умолчанию вместо Null .
Вы можете установить для свойства .Value значение «» в событии Form_Load . Но . Я наблюдал там некоторую неустойчивую работу; кажется, что .Value иногда меняется с «» обратно на Null , и я еще не выяснил обстоятельства.
Поэтому лучше всего определить .ControlSource в =»» либо в представлении «Дизайн», либо в событии Form_Load . Но имейте в виду, что этот niblet сложен из-за встроенных двойных кавычек, и его может быть сложно прочитать.
Вот несколько способов сделать это:
- myTextbox.ControlSource = «=» & «» «» «(пять двойных кавычек подряд)
- myTextbox.ControlSource = «=» & Chr (34) & Chr (34)
- И т. Д. И т. Д., Есть много способов сделать это .
Кроме того, вот расширенный лакомый кусочек. Если вы установите для свойства .TextFormat значение Rich Text , вы можете отформатировать текст в нем жирным шрифтом, курсивом, цветами и т. Д. Но будьте осторожны (опять же), начиная с Office 2007, исходного формата Microsoft RTF был выведен из эксплуатации в пользу «мини» версии HTML, которая поддерживает только несколько тегов, связанных с форматированием шрифтов и абзацев.
В качестве примера предположим, что вы хотите, чтобы в текстовом поле отображался маленький символ флажка ASCII со словом «действительный» курсивом рядом с ним, и он был сделан зеленым. Вы можете это сделать, но все должно быть в HTML, и его нелегко прочитать:
Если текстовое поле является элементом управления ReadOnly, свойство value не будет использоваться, но если вы установите значение текста, значение все равно будет использоваться в данных формы.
Источник
Vba excel value или text
Cell Values And Displayed Text
When you are working in Excel, either with formulas or with Visual Basic For Applications (VBA) code, it is important to understand the difference between the actual value of a cell and what is displayed on the screen. The actual value of the cell is what Excel stores internally and what it uses in formulas and calculations. This is not necessarily the same as what you see displayed on the screen or printed on your reports. It is important that you understand the difference between the two — otherwise, your formulas may not work as expected.
For example, as you know, dates are stored as the number of days since 0-Jan-1900. (Click here for more information about working with dates and times.) Excel will store the date as a simple number. The date 7-April-2001 is stored internally by Excel as the number 36,988. However, it is quite unlikely that you will display a date in this «serial» format. More likely, you’ll display it as 4/7/2001 or perhaps a day name (e.g., «Sat»). On this page, we’ll refer to actual value of the cell as «value» and the displayed text as «text».
Cell Values In Formulas
Let’s look at this example further. In cell A1, enter 7-April-2001. This should display in the default format for your language. Now, in A2, enter the formula =IF(A1=»4/7/2001″,»Yes»,»No») . This will display No, because the value of A1 is not the character string «4/7/2001». Now, in A3, enter the formula
=IF(A1=36988,»Yes»,»No») . This will return Yes, because the value of the cell is, in fact, 36,988.
It is unlikely that you’ll hard code dates like this. However, you may often format a cell to display just the day of week. Change the number format of A1 to ddd. This will display Sat. In cell A4, enter the formula
=IF(A1=»Sat»,»Yes»,»No») . Again, this will return No, because the value of A1 is not equal to Sat. The text of A1 is indeed Sat, but the value is not.
You can use the TEXT function to format the value of a cell in a formula, and then compare that to another value. For example, you can use the following formula to determine if A1 is a Saturday
=IF(TEXT(A1,»ddd»)=»Sat»,»Yes»,»No») .
The distinction between value and text is important not just for dates, but for numbers as well. For example, suppose B1 contains the number 0.4999999, but is is formatted to display only one decimal place. In this case, B1 will display 0.5. But the formula =IF(B1>=0.5,»Yes»,»No») will return No, because the value of B1 is still less than 0.5, even though it appears to be equal to 0.5. In a case like this, you may want to use the ROUND function to round the value properly before the comparison:
=IF(ROUND(B1,1)>=0.5,»Yes»,»No») .
If you fail to take into account the differences between a cell’s actual value and the text that is displayed on the screen, your formulas may not work as expected, and it may appear the Excel isn’t working properly when in fact it really is.
Cell Values In VBA
When you are writing code in VBA, you can use the Text property of a Range object to get the text which is displayed on the screen. The Value property returns the actual value of the cell. For example,
Range(«C1»).Value = 0.49999999
Range(«C1»).NumberFormat = «0.00»
Debug.Print «The Value property is: » & Range(«C1»).Value
Debug.Print «The Text property is: » & Range(«C1»).Text
You’ll need to have the Immediate window of the VBA Editor visible in order to see these results. Press CTRL+G or choose Immediate Window from the View menu.
The Text property is read-only. You cannot assign a value to this property.
It should also be noted that while a cell may contain up to 32K characters of text, the Text property is limited to 1024 characters.
Источник
Distinction between using .text and .value in VBA Access
I am passing the textbox1.text values into a query and sometimes into a string:
How do I know when I should put combor1 = comboReason1.Value ?
Also, why do I need to set focus for a control to reference its property? That doesn’t make sense to me.
Also, when I set combor4 = comboReason4.Value and the .value is null, then I get an error about invalid use of null.
5 Answers 5
- «.text» gives you what is displayed on the screen
- «.value» gives you the underlying value
Both usually give the same result, except when the corresponding control is
- a combobox or listbox control
- the displayed value differs from the bound column
- id_Person is a combobox control in a form
- the rowsource is «SELECT id_Person, personName FROM Tbl_Person»
- column widths are «0cm;3cm»
- bound column is 1
In this situation:
- id_Person.text displays Tbl_Person.personName
- id_Person.value displays Tbl_Person.id_Person.
.text property is available only when the corresponding control has the focus.
.text is a string value, therefore it cannot be Null, while .value can be Null
EDIT: .text can only be called when the control has the focus, while .value can be called any time .
You can use the Text property to set or return the text contained in a text box or in the text box portion of a combo box.
To set or return a control’s Text property, the control must have the focus, or an error occurs. To move the focus to a control, you can use the SetFocus method or GoToControl action.
You can use the Value property to determine or specify if a control is selected, the selected value or option within the control, the text contained in a text box control, or the value of a custom property.
The Value property returns or sets a control’s default property, which is the property that is assumed when you don’t explicitly specify a property name. In the following example, because the default value of the text box is the value of the Text property, you can refer to its Text property setting without explicitly specifying the name of the property.
.text starts the field validation and causes an error if field validation is hurt. .value doesn’t start the field validation, you may enter ANY value
This thread and the answers herein explain the issue well. There are a couple of additional points I’d like to add, which I’ve found through experimentation:
The order of precedence of the properties is:
From what I’ve been seeing in Access 2007, if .ControlSource is undefined when the form opens, .Value will be Null .
If you set the .ControlSource property to =»» (an empty string), that will cause the .Value property to default to that instead of Null .
You can set the .Value property to «» in the Form_Load event. But. I’ve been seeing some erratic operation there; it seems as if .Value sometimes changes from «» back to Null , and I haven’t yet worked out the circumstances.
So it seems best to define .ControlSource to =»» , either in Design View or in the Form_Load event. But be forewarned, that niblet is tricky because of the embedded double quotes, and it can be tricky to read.
Some ways to do it are:
- myTextbox.ControlSource = «=» & «»»»» (five double quotes in a row)
- myTextbox.ControlSource = «=» & Chr(34) & Chr(34)
- Etc, etc, there are many ways to do it.
Also, here’s an extended tidbit. If you set the .TextFormat property to Rich Text , you can format the text in it with bold, italic, colors, etc. But be forewarned (again), beginning with Office 2007, the original Microsoft RTF format was decommissioned in favor of a «mini» version of HTML that only supports a few tags related to formatting fonts and paragraphs.
As an example, say you want the textbox to display the little ASCII checkbox character with the word «valid» in italics next to it, and make it all green. You can do it, but it all has to be in HTML, and it’s not easy to read:
Источник
Свойства ячейки, часто используемые в коде VBA Excel. Демонстрация свойств ячейки, как структурной единицы объекта Range, на простых примерах.
Объект Range в VBA Excel представляет диапазон ячеек. Он (объект Range) может описывать любой диапазон, начиная от одной ячейки и заканчивая сразу всеми ячейками рабочего листа.
Примеры диапазонов:
- Одна ячейка –
Range("A1")
. - Девять ячеек –
Range("A1:С3")
. - Весь рабочий лист в Excel 2016 –
Range("1:1048576")
.
Для справки: выражение Range("1:1048576")
описывает диапазон с 1 по 1048576 строку, где число 1048576 – это номер последней строки на рабочем листе Excel 2016.
В VBA Excel есть свойство Cells объекта Range, которое позволяет обратиться к одной ячейке в указанном диапазоне (возвращает объект Range в виде одной ячейки). Если в коде используется свойство Cells без указания диапазона, значит оно относится ко всему диапазону активного рабочего листа.
Примеры обращения к одной ячейке:
Cells(1000)
, где 1000 – порядковый номер ячейки на рабочем листе, возвращает ячейку «ALL1».Cells(50, 20)
, где 50 – номер строки рабочего листа, а 20 – номер столбца, возвращает ячейку «T50».Range("A1:C3").Cells(6)
, где «A1:C3» – заданный диапазон, а 6 – порядковый номер ячейки в этом диапазоне, возвращает ячейку «C2».
Для справки: порядковый номер ячейки в диапазоне считается построчно слева направо с перемещением к следующей строке сверху вниз.
Подробнее о том, как обратиться к ячейке, смотрите в статье: Ячейки (обращение, запись, чтение, очистка).
В этой статье мы рассмотрим свойства объекта Range, применимые, в том числе, к диапазону, состоящему из одной ячейки.
Еще надо добавить, что свойства и методы объектов отделяются от объектов точкой, как в третьем примере обращения к одной ячейке: Range("A1:C3").Cells(6)
.
Свойства ячейки (объекта Range)
Свойство | Описание |
---|---|
Address | Возвращает адрес ячейки (диапазона). |
Borders | Возвращает коллекцию Borders, представляющую границы ячейки (диапазона). Подробнее… |
Cells | Возвращает объект Range, представляющий коллекцию всех ячеек заданного диапазона. Указав номер строки и номер столбца или порядковый номер ячейки в диапазоне, мы получаем конкретную ячейку. Подробнее… |
Characters | Возвращает подстроку в размере указанного количества символов из текста, содержащегося в ячейке. Подробнее… |
Column | Возвращает номер столбца ячейки (первого столбца диапазона). Подробнее… |
ColumnWidth | Возвращает или задает ширину ячейки в пунктах (ширину всех столбцов в указанном диапазоне). |
Comment | Возвращает комментарий, связанный с ячейкой (с левой верхней ячейкой диапазона). |
CurrentRegion | Возвращает прямоугольный диапазон, ограниченный пустыми строками и столбцами. Очень полезное свойство для возвращения рабочей таблицы, а также определения номера последней заполненной строки. |
EntireColumn | Возвращает весь столбец (столбцы), в котором содержится ячейка (диапазон). Диапазон может содержаться и в одном столбце, например, Range("A1:A20") . |
EntireRow | Возвращает всю строку (строки), в которой содержится ячейка (диапазон). Диапазон может содержаться и в одной строке, например, Range("A2:H2") . |
Font | Возвращает объект Font, представляющий шрифт указанного объекта. Подробнее о цвете шрифта… |
HorizontalAlignment | Возвращает или задает значение горизонтального выравнивания содержимого ячейки (диапазона). Подробнее… |
Interior | Возвращает объект Interior, представляющий внутреннюю область ячейки (диапазона). Применяется, главным образом, для возвращения или назначения цвета заливки (фона) ячейки (диапазона). Подробнее… |
Name | Возвращает или задает имя ячейки (диапазона). |
NumberFormat | Возвращает или задает код числового формата для ячейки (диапазона). Примеры кодов числовых форматов можно посмотреть, открыв для любой ячейки на рабочем листе Excel диалоговое окно «Формат ячеек», на вкладке «(все форматы)». Свойство NumberFormat диапазона возвращает значение NULL, за исключением тех случаев, когда все ячейки в диапазоне имеют одинаковый числовой формат. Если нужно присвоить ячейке текстовый формат, записывается так: Range("A1").NumberFormat = "@" . Общий формат: Range("A1").NumberFormat = "General" . |
Offset | Возвращает объект Range, смещенный относительно первоначального диапазона на указанное количество строк и столбцов. Подробнее… |
Resize | Изменяет размер первоначального диапазона до указанного количества строк и столбцов. Строки добавляются или удаляются снизу, столбцы – справа. Подробнее… |
Row | Возвращает номер строки ячейки (первой строки диапазона). Подробнее… |
RowHeight | Возвращает или задает высоту ячейки в пунктах (высоту всех строк в указанном диапазоне). |
Text | Возвращает форматированный текст, содержащийся в ячейке. Свойство Text диапазона возвращает значение NULL, за исключением тех случаев, когда все ячейки в диапазоне имеют одинаковое содержимое и один формат. Предназначено только для чтения. Подробнее… |
Value | Возвращает или задает значение ячейки, в том числе с отображением значений в формате Currency и Date. Тип данных Variant. Value является свойством ячейки по умолчанию, поэтому в коде его можно не указывать. |
Value2 | Возвращает или задает значение ячейки. Тип данных Variant. Значения в формате Currency и Date будут отображены в виде чисел с типом данных Double. |
VerticalAlignment | Возвращает или задает значение вертикального выравнивания содержимого ячейки (диапазона). Подробнее… |
В таблице представлены не все свойства объекта Range. С полным списком вы можете ознакомиться не сайте разработчика.
Простые примеры для начинающих
Вы можете скопировать примеры кода VBA Excel в стандартный модуль и запустить их на выполнение. Как создать стандартный модуль и запустить процедуру на выполнение, смотрите в статье VBA Excel. Начинаем программировать с нуля.
Учтите, что в одном программном модуле у всех процедур должны быть разные имена. Если вы уже копировали в модуль подпрограммы с именами Primer1, Primer2 и т.д., удалите их или создайте еще один стандартный модуль.
Форматирование ячеек
Заливка ячейки фоном, изменение высоты строки, запись в ячейки текста, автоподбор ширины столбца, выравнивание текста в ячейке и выделение его цветом, добавление границ к ячейкам, очистка содержимого и форматирования ячеек.
Если вы запустите эту процедуру, информационное окно MsgBox будет прерывать выполнение программы и сообщать о том, что произойдет дальше, после его закрытия.
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 |
Sub Primer1() MsgBox «Зальем ячейку A1 зеленым цветом и запишем в ячейку B1 текст: «Ячейка A1 зеленая!»» Range(«A1»).Interior.Color = vbGreen Range(«B1»).Value = «Ячейка A1 зеленая!» MsgBox «Сделаем высоту строки, в которой находится ячейка A2, в 2 раза больше высоты ячейки A1, « _ & «а в ячейку B1 вставим текст: «Наша строка стала в 2 раза выше первой строки!»» Range(«A2»).RowHeight = Range(«A1»).RowHeight * 2 Range(«B2»).Value = «Наша строка стала в 2 раза выше первой строки!» MsgBox «Запишем в ячейку A3 высоту 2 строки, а в ячейку B3 вставим текст: «Такова высота второй строки!»» Range(«A3»).Value = Range(«A2»).RowHeight Range(«B3»).Value = «Такова высота второй строки!» MsgBox «Применим к столбцу, в котором содержится ячейка B1, метод AutoFit для автоподбора ширины» Range(«B1»).EntireColumn.AutoFit MsgBox «Выделим текст в ячейке B2 красным цветом и выровним его по центру (по вертикали)» Range(«B2»).Font.Color = vbRed Range(«B2»).VerticalAlignment = xlCenter MsgBox «Добавим к ячейкам диапазона A1:B3 границы» Range(«A1:B3»).Borders.LineStyle = True MsgBox «Сделаем границы ячеек в диапазоне A1:B3 двойными» Range(«A1:B3»).Borders.LineStyle = xlDouble MsgBox «Очистим ячейки диапазона A1:B3 от заливки, выравнивания, границ и содержимого» Range(«A1:B3»).Clear MsgBox «Присвоим высоте второй строки высоту первой, а ширине второго столбца — ширину первого» Range(«A2»).RowHeight = Range(«A1»).RowHeight Range(«B1»).ColumnWidth = Range(«A1»).ColumnWidth MsgBox «Демонстрация форматирования ячеек закончена!» End Sub |
Вычисления в ячейках (свойство Value)
Запись двух чисел в ячейки, вычисление их произведения, вставка в ячейку формулы, очистка ячеек.
Обратите внимание, что разделителем дробной части у чисел в VBA Excel является точка, а не запятая.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Sub Primer2() MsgBox «Запишем в ячейку A1 число 25.3, а в ячейку B1 — число 34.42» Range(«A1»).Value = 25.3 Range(«B1»).Value = 34.42 MsgBox «Запишем в ячейку C1 произведение чисел, содержащихся в ячейках A1 и B1» Range(«C1»).Value = Range(«A1»).Value * Range(«B1»).Value MsgBox «Запишем в ячейку D1 формулу, которая перемножает числа в ячейках A1 и B1» Range(«D1»).Value = «=A1*B1» MsgBox «Заменим содержимое ячеек A1 и B1 на числа 6.258 и 54.1, а также активируем ячейку D1» Range(«A1»).Value = 6.258 Range(«B1»).Value = 54.1 Range(«D1»).Activate MsgBox «Мы видим, что в ячейке D1 произведение изменилось, а в строке состояния отображается формула; « _ & «следующим шагом очищаем задействованные ячейки» Range(«A1:D1»).Clear MsgBox «Демонстрация вычислений в ячейках завершена!» End Sub |
Так как свойство Value является свойством ячейки по умолчанию, его можно было нигде не указывать. Попробуйте удалить .Value из всех строк, где оно встречается и запустить код заново.
Различие свойств Text, Value и Value2
Построение с помощью кода VBA Excel таблицы с результатами сравнения того, как свойства Text, Value и Value2 возвращают число, дату и текст.
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 |
Sub Primer3() ‘Присваиваем ячейкам всей таблицы общий формат на тот ‘случай, если формат отдельных ячеек ранее менялся Range(«A1:E4»).NumberFormat = «General» ‘добавляем сетку (границы ячеек) Range(«A1:E4»).Borders.LineStyle = True ‘Создаем строку заголовков Range(«A1») = «Значение» Range(«B1») = «Код формата» ‘формат соседней ячейки в столбце A Range(«C1») = «Свойство Text» Range(«D1») = «Свойство Value» Range(«E1») = «Свойство Value2» ‘Назначаем строке заголовков жирный шрифт Range(«A1:E1»).Font.Bold = True ‘Задаем форматы ячейкам A2, A3 и A4 ‘Ячейка A2 — числовой формат с разделителем триад и двумя знаками после запятой ‘Ячейка A3 — формат даты «ДД.ММ.ГГГГ» ‘Ячейка A4 — текстовый формат Range(«A2»).NumberFormat = «# ##0.00» Range(«A3»).NumberFormat = «dd.mm.yyyy» Range(«A4»).NumberFormat = «@» ‘Заполняем ячейки A2, A3 и A4 значениями Range(«A2») = 2362.4568 Range(«A3») = CDate(«01.01.2021») ‘Функция CDate преобразует текстовый аргумент в формат даты Range(«A4») = «Озеро Байкал» ‘Заполняем ячейки B2, B3 и B4 кодами форматов соседних ячеек в столбце A Range(«B2») = Range(«A2»).NumberFormat Range(«B3») = Range(«A3»).NumberFormat Range(«B4») = Range(«A4»).NumberFormat ‘Присваиваем ячейкам C2-C4 значения свойств Text ячеек A2-A4 Range(«C2») = Range(«A2»).Text Range(«C3») = Range(«A3»).Text Range(«C4») = Range(«A4»).Text ‘Присваиваем ячейкам D2-D4 значения свойств Value ячеек A2-A4 Range(«D2») = Range(«A2»).Value Range(«D3») = Range(«A3»).Value Range(«D4») = Range(«A4»).Value ‘Присваиваем ячейкам E2-E4 значения свойств Value2 ячеек A2-A4 Range(«E2») = Range(«A2»).Value2 Range(«E3») = Range(«A3»).Value2 Range(«E4») = Range(«A4»).Value2 ‘Применяем к таблице автоподбор ширины столбцов Range(«A1:E4»).EntireColumn.AutoFit End Sub |
Результат работы кода:
В таблице наглядно видна разница между свойствами Text, Value и Value2 при применении их к ячейкам с отформатированным числом и датой. Свойство Text еще отличается от Value и Value2 тем, что оно предназначено только для чтения.
This thread and the answers herein explain the issue well. There are a couple of additional points I’d like to add, which I’ve found through experimentation:
The order of precedence of the properties is:
.ControlSource
.Value
.Text
From what I’ve been seeing in Access 2007, if .ControlSource
is undefined when the form opens, .Value
will be Null
.
If you set the .ControlSource
property to =""
(an empty string), that will cause the .Value
property to default to that instead of Null
.
You can set the .Value
property to ""
in the Form_Load
event. But…I’ve been seeing some erratic operation there; it seems as if .Value
sometimes changes from ""
back to Null
, and I haven’t yet worked out the circumstances.
So it seems best to define .ControlSource
to =""
, either in Design View or in the Form_Load
event. But be forewarned, that niblet is tricky because of the embedded double quotes, and it can be tricky to read.
Some ways to do it are:
- myTextbox.ControlSource = «=» & «»»»» (five double quotes in a row)
- myTextbox.ControlSource = «=» & Chr(34) & Chr(34)
- Etc, etc, there are many ways to do it…
Also, here’s an extended tidbit. If you set the .TextFormat
property to Rich Text
, you can format the text in it with bold, italic, colors, etc. But be forewarned (again), beginning with Office 2007, the original Microsoft RTF format was decommissioned in favor of a «mini» version of HTML that only supports a few tags related to formatting fonts and paragraphs.
As an example, say you want the textbox to display the little ASCII checkbox character with the word «valid» in italics next to it, and make it all green. You can do it, but it all has to be in HTML, and it’s not easy to read:
myTextbox.TextFormat = acTextFormatHTMLRichText
myTextbox.ControlSource = "=" & Chr(34) & "<font color=#80CA45><font face=Wingdings>" & _
Chr(254) & "</font> <font face=Calibri><i>Valid.</i></font></font>" & Chr(34)
I was intrigued by a recent post pointing out that using .Text to retrieve data from Excel ranges got slower and slower as you iterated through the rows. So I took some time to explore and compare the three main properties (Range.Value, Range.Value2 and Range.Text) for getting result values from an Excel Range into VBA.
Of course, as you will see, they each have their own peculiarities and advantages.
Range.Text
This gets the formatted value of a cell. Actually it looks like .Text gets the value from the cell and then formats it, because the more complex the formatting the slower it is.
.Text is a read-only property, so you cannot set it directly.
If you try getting .Text from multiple cells into a variant (varr = Range(“A1:A10”).Text) you do NOT get an array of results. Instead if all the cells in the range contain the same value formatted in the same way you get a single formatted value, but if ANY of the cells has different values or formats you get Null ( this could be a useful trick).
When used inside a UDF you can use .Text to get the formatted value of the calling cell as it was before the UDF was called (you can’t do this with .Value or .Value 2 without causing a circular reference). Here is an example that adds an extra . on each calculation.
Function LastValue() Dim var As Variant Application.Volatile var = Application.Caller.Text Debug.Print var var = var & "." LastValue = var End Function
The major drawback of .Text when used this way is that it gives you the formatted value, so the value you get could be ### if the user has set an inappropriate zoom or column width, or numbers could be retrieved as 1E+18 or …
Range.Value
This mostly gets the underlying native Excel value (the only native Excel Data Types are double-precision numbers, text, Boolean, errors, empty) from the cell.
But if the cell is formatted as a date or currency then Range.Value converts the underlying double-precision value into a VBA date or currency variable before passing it to the VBA variable used in the assignment statement. Since VBA currency only has 4 decimal places this can cause a loss of accuracy. Suppose cell G4 has a value of 123.456789 formatted as currency. Then Range(“g4”).Value will retrieve a value of 123.4568 rather than the actual value!
If you assign this to a Variant you get a variant with a subtype of currency, but if you assign it to a Double then the value first gets converted to currency datatype and truncated, and then the currency datatype gets converted to a double.
Update: Even worse – assigning a VBA currency variable to a cell using .Value rounds the value to 2 decimal places regardless of cell formatting. This VBA code starts with 123.45679123, converts it currency datatype (rounds to 4 decimal places) which gives 123.4568, and then inserts into a cell using .Value which gives a value in Excel of 123.46 (rounds to 2 decimal places).
So using code like Range(“A2”).Value=Range(“A1”).Value when A1 is formatted as currency will round the actual resulting value in A2 to 2 decimal places.
Maybe using .Value to retrieve cells formatted as dates into a variant is useful because then you can use IsDate() to detect that the cell was a date.
Update: There is a problem using .Value to get a date from Excel into a variant or a VBA Date and then passing it back to a Worksheet function like VLOOKUP: this will fail because VLOOKUP does not understand the combination of a number and a date format code.
Range.Value is an efficient way of transferring a range of cell values to VBA because you can assign the Range to a variant variable and the you get a variant containing a 2-dimensional array of variants. This is much more efficient that looping on the cells one-by-one.
.Value is (unfortunately) the default property of the Range object.
Range.Value2
This works the same way as Range.Value, except that it does not check the cell format and convert to Date or Currency. And that’s probably why its faster than .Value when retrieving numbers.
So .Value2 really should be the default, and is definitely the one to use 99% of the time.
Performance Comparison
So how do these properties compare for speed? Here is my test code:
Sub textit() Dim dTime As Double Dim j As Long Dim jStart As Long Dim var As Variant dTime = MicroTimer() For jStart = 1 To 40000 Step 5000 dTime = MicroTimer For j = 1 To 5000 var = Range("a1").Offset(jStart + j - 2, 0).Text Next j dTime = MicroTimer - dTime Debug.Print dTime Next jStart End Sub
I ran this using a fresh worksheet with test data of numbers in the first 40000 rows.
The first run showed more-or-less constant time for each block. Then I changed the row-height of 10 rows at random intervals. The next run (.Text(2) is much slower, and the times increase from block to block.
So what’s going on: why so much slower with times increasing?
Well it turns out that once enough row-heights have been changed the time for .Text is a function of the number of rows between the selected visible rows on the screen and the row being processed!!!!
(And No I don’t know why, .Text must be doing some sort of cumulative row height calculation).
So if you add Range(“a1”).Offset(jStart).Select immediately after the For jStart = 1 To 40000 Step 5000 you get a faster and more constant set of times. Note you have to have Application.Screenupdating =True or this trick won’t work.
Finally I replaced .Text with .Value and then with .Value2, and then used a variant array instead of the inner loop to get the full set of timings:
Conclusions
- .Text is seriously slow even if you bypass the row-height problem.
- .Value can seriously damage your numbers
- .Value2 is faster than .value with numbers (no significant difference with text)
- .Value2 using a variant array is much the fastest way to go
So do you ever use .Text? And if so why?
Я не прошу о помощи с любым script, но мой вопрос объясняется. В последнее время я делал много сценариев VB в Excel, поэтому я действительно имею в виду Excel в этом вопросе. В чем разница между .text,.value и .value2? Например, когда следует использовать target.text, target.value и target.value2? Я никогда не использовал параметр value2, но все равно хотел бы знать, для чего он используется.
Иногда, если я использую .text, он дает мне ошибку, и мне нужно использовать .value, когда я только проверяю или манипулирую текстом внутри ячейки. Тогда иногда, когда я думаю, что должен использовать .value, я получаю сообщение об ошибке, и мне нужно использовать .text. Обычно он принимает или без проблемы, но иногда это имеет значение. Я знаю, что для этого должна быть какая-то логика, но я, похоже, не понимаю ее.
Я также узнал, что если вы просто оставите его в качестве цели, не указав .text или .value, он будет изначально работать, но тогда что-то, что кто-то сделает, в конечном итоге приведет к ошибке script, поэтому всегда лучше использовать что-то на нем. Я предполагаю, что я спрашиваю, может ли кто-нибудь дать мне какое-то руководство, эмпирическое правило о том, как правильно использовать каждый и когда нужно его использовать.
Спасибо за объяснение, ребята. Я как бы понимаю это лучше. Они оба являются хорошими объяснениями. Ниже приведен небольшой пример моего кода, который работает. Я думал, что это должен быть target.text, но это будет ошибка, поэтому, когда я использовал target.value, он работал.
If LCase(Target.Value) = LCase("HLO") And Target.Column = 15 Then
Target.Value = "Higher Level Outage"
End If
Я все еще немного смущен, потому что, когда я думаю о ценности или ценности2, особенно после ваших ответов, которые вы предоставили, я думаю, что они должны использоваться только для чисел. Тем не менее, в моем примере я говорю о строгом тексте, который много относится к моему script (текст в ячейках, а не по номерам).