Функция Len не дает правильное значение - PullRequest
0 голосов
/ 28 февраля 2020

У меня возникают трудности с получением функции Len () для получения правильной длины числа.

Здесь есть фрагмент кода, который имеет трудности:

Spec = Len(Range("J8")) - x
intermit = Range("I8") - Range("J8")
Low = Len(intermit)

MsgBox "Lower Spec: " & intermit & " Length: " & Low

intermit = Range("I8") + Range("J8")
High = Len(WorksheetFunction.Text(intermit, 0))
MsgBox "Upper Spec: " & intermit & " Length: " & High

Диапазон ( «I8») = 0,0140

Диапазон («J8») = 0,0002

В окнах сообщений должно отображаться следующее:

Lower Spe c: 0,0138 Length : 6

Верхняя Spe c: 0,0142 Длина: 6

Однако они отображаются:

Нижняя Spe c: 0,0138 Длина: 8

Upper Spe c: 0,0142 Длина: 8

Я попытался преобразовать переменную прерывания в текст, но затем она вернулась бы как 0. Я не знаю, откуда берутся дополнительные 2 символа, которые подсчитывает функция .

1 Ответ

2 голосов
/ 28 февраля 2020

Не используйте WorksheetFunction.Text для преобразования Variant/Double в String; правильная строка формата для него была бы "@", а не 0 - но вам не нужно задействовать функции рабочего листа, стандартная библиотека VBA уже предоставляет модуль VBA.Conversion, который предоставляет вам множество функций преобразования, включая CStr.

Но функция Len находится в модуле VBA.Strings, что предполагает, что преобразование строк в любом случае будет неявным - не повредит сделать это преобразование явным, используя соответствующую функцию преобразования особенно если учесть, что мы имеем дело с необъявленными переменными, которые во время выполнения будут Variant/Double, если предположить, что значения ячеек на самом деле равны c значениям.

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

Dim intermitLow As Double
intermitLow = Sheet2.Range("I8").Value - Sheet2.Range("J8").Value
Debug.Print intermitLow, Len(CStr(intermitLow))

Dim intermitHigh As Double
intermitHigh = Sheet2.Range("I8").Value + Sheet2.Range("J8").Value
Debug.Print intermitHigh, Len(CStr(intermitHigh))

Вывод с I8 = 0,014 (что незначительный конечный ноль в ОП беспокоит) и J8 = 0,0002:

 0.0138        6 
 0.0142        6 

Обратите внимание, что я ' m явно квалифицирует вызовы Range членов с правильным Worksheet объектом, здесь Sheet2 (см. CodeName: Sheet1 для всего, что вам нужно знать о кодовых именах листа). Если ваш код написан в стандартном модуле, то неквалифицированные Range вызовы являются неявными ActiveSheet ссылками , то есть он ссылается на любой рабочий лист, который оказывается активным в то время , что делает код более хрупким, чем он должен быть - хотя здесь это не является проблемой, поскольку мы работаем с ожидаемыми значениями.

Рассмотрим только чтение значений ячеек один раз - не нужно чтобы каждый раз снова попадать на лист:

Dim value1 As Double 'todo use a meaningful name
'note: possible type mismatch on assignment depending on the data type of .Value
value1 = Sheet2.Range("I8").Value

Dim value2 As Double 'todo use a meaningful name
'note: possible type mismatch on assignment depending on the data type of .Value
value2 = Sheet2.Range("J8").Value

Dim intermitLow As Double
intermitLow = value1 - value2
Debug.Print intermitLow, Len(CStr(intermitLow))

Dim intermitHigh As Double
intermitHigh = value1 + value2
Debug.Print intermitHigh, Len(CStr(intermitHigh))

Избегайте повторного использования переменных / идентификаторов для различных целей в рамках процедуры и всегда объявляйте все переменные (Option Explicit вверху каждого модуля принудительно Вы , чтобы сделать это).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...