Использование округленных значений в качестве входов для VLOOKUP, что приводит к возврату # N / A - PullRequest
0 голосов
/ 02 января 2019

У меня есть следующие значения в Excel (A1 и т.д. - ссылки на ячейки):

A1 = 0.0625 'User Input
A2 = ROUNDDOWN(A1,2) = 0.06 
A3 = ROUNDUP(A1,2) = 0.07 

Затем я использую значения A2 и A3 в вызовах VLOOKUP:

B2 = IF(A2>0.3,"Out of Range",VLOOKUP(A2,data!$A$42:$B$71,2,FALSE))
B3 = IF(A3>0.3,"Out of Range",VLOOKUP(A3,data!$A$42:$B$71,2,FALSE))

B2 заполняется правильно. B3 возвращает #N/A

Диапазон, в котором я ищу, содержит следующие данные:

enter image description here

Доступны все необходимые данные, кажется, что лист не может получить значение для 0,07. Кто-нибудь может понять почему? Кажется, он работает для всех других значений, которые я пробовал до сих пор.

КЛЮЧЕВАЯ ИНФОРМАЦИЯ Если я удаляю A3 = ROUNDUP(A1,2) и просто набираю 0.07 в ячейку A3, все работает отлично. Поэтому мне любопытно, что делает ROUNDUP, так как это, по-видимому, приводит к падению VLOOKUP.

Я пытался вложить функцию ROUNDUP в мое уравнение VLOOKUP, но получаю тот же результат.

Ответы [ 2 ]

0 голосов
/ 02 января 2019

В качестве дополнения к данному ответу:

Спецификация IEEE арифметики с плавающей запятой не виновата в этой проблеме.Вместо этого это явно ошибка в реализации CEILING и ROUNDUP.Округление должно быть решением при использовании чисел с плавающей запятой и не должно быть проблемой.

Благодаря тому, что файлы *.xlsx являются просто ZIP-архивами, мы можем просто распаковать его и получитьзаглянуть в то, что действительно хранится.В качестве примера в /xl/worksheets/sheet1.xml мы находим:

<sheetData>
 <row r="1" spans="1:2">
  <c r="A1">
   <f>ROUNDUP(0.0625,2)</f>
   <v>6.9999999999999993E-2</v>
  </c>
  <c r="B1">
   <f>ROUND(ROUNDUP(0.0625,2),2)</f>
   <v>7.0000000000000007E-2</v>
  </c>
 </row>
 <row r="2" spans="1:2">
  <c r="A2">
   <f>CEILING(0.0625,0.01)</f>
   <v>7.0000000000000007E-2</v>
  </c><c r="B2">
   <f>ROUND(CEILING(0.0625,0.01),2)</f>
   <v>7.0000000000000007E-2</v>
  </c>
 </row>
 <row r="3" spans="1:2">
  <c r="A3">
   <f>ROUNDUP(15.25,1)</f>
   <v>15.299999999999999</v>
  </c>
  <c r="B3">
   <f>ROUND(ROUNDUP(15.25,1),1)</f>
   <v>15.3</v>
  </c>
 </row>
 <row r="4" spans="1:2">
  <c r="A4">
   <f>CEILING(15.1,0.1)</f>
   <v>15.100000000000001</v>
  </c>
  <c r="B4">
   <f>ROUND(CEILING(15.1,0.1),1)</f>
   <v>15.1</v>
  </c>
 </row>
</sheetData>

Как мы видим здесь, утверждение: «хранение только 15 значащих цифр точности» не совсем верно.Вместо этого хранятся действительные числа в точности IEEE 754 double с точностью до 17 цифр.Кроме того, ROUNDUP и CEILING иногда не хранят округленные значения.И это ошибка на мой взгляд, как я уже сказал.ROUND и ROUNDDOWN всегда хранят округленные значения, как и должно быть.

0 голосов
/ 02 января 2019

Благодаря @Axel Richter и @SJR в комментариях может показаться, что эта ошибка связана со способом, которым Excel сохраняет значения после округления.См. ответ на этот предыдущий поток для аналогичного примера с функцией Ceiling.

Похоже, есть несколько обходных путей:

1) Использование INT ()

=INT(100*ROUNDUP(A1,2))/100

Вместо того, чтобы просто использовать ROUNDUP, проблема решается.

2) Принудительная работа Excel с отображаемой точностью

File > Options > Advanced > Set Precision As Displayed

Однако это может привести к потере данных и не совсем оптимальное решение

3) КРУГЛЫЙ КРУГЛЫЙ ПУНКТ

ROUND(ROUNDUP(A1, 2), 2)

Спасибо @Kanak за это.

Другие комментарии

В моем случае использование =CEILING(A1,0.01) работает, но в вышеупомянутом предыдущем вопросе, CEILING был на самом деле проблемой, так что это не должно рассматриваться какрешение.

Применение ответа @Axel Richter's ранее на мой вопрос показывает, что использование ROUNDUP может привести к небольшой разнице между тем, что отображается в ячейке, и значением, которое фактически хранит Excel.В моем случае ошибка в округлении выглядит следующим образом:

 Sub testRoundup()

 Dim v As Double, test As Boolean, diff As Double

 v = [ROUNDUP(0.0625,2)]            '0.07
 test = (v = 0.07)                  'FALSE
 diff = 0.07 - v                    '1.38777878078145E-17

End Sub

Другой хороший ресурс .

...