Страницы: 1
RSS
Очистка ячеек, содержащих дробные значения.
 
Подскажите пожалуйста, как автоматизировать процесс очистки ячеек массива, которые содержат дробные (не целые) числа? Есть массив, в котором есть целые и дробные числа. Дробные  для дальнейших расчётов не нужны. Позиция каждой ячейки должна оставаться неизменной.Т.е., на выходе должны иметь ячейки, либо содержащие целое число, либо пустые. Заранее спасибо.
 
Выделить диапазон ячеек и запустить макрос:  
Sub IntOnly()  
 Dim a, c&, cs&, r&, rs&  
 With Selection  
   a = .Value  
   If Not IsArray(a) Then  
     If a <> Round(a, 0) Then .ClearContents  
     Exit Sub  
   End If  
   rs = UBound(a, 1)  
   cs = UBound(a, 2)  
   For r = 1 To rs  
     For c = 1 To cs  
       If a(r, c) <> Round(a(r, c), 0) Then a(r, c) = Empty  
     Next  
   Next  
   .Value = a  
 End With  
End Sub
 
Или в дальнейших расчетах использовать ЦЕЛОЕ().
 
Здравствуйте, Владимир!  
Хотя и не я автор топика, но возник такой вопрос.  
В VBA нет такой возможности как в Excel(экс возвращает значение по условию), использовать if таким образом:  
ЕСЛИ =MOD(A1:B3,INT(A1:B3))<> 0, ТО очистить содержимое?
 
Спасибо огромное ZVI за макрос, работает шикарно, и vikttur за подсказку с ЦЕЛОЕ().
 
{quote}{login=Serge 007}{date=01.04.2012 11:20}{thema=}{post}Здравствуйте, Владимир!  
Хотя и не я автор топика, но возник такой вопрос.  
В VBA нет такой возможности как в Excel(экс возвращает значение по условию), использовать if таким образом:  
ЕСЛИ =MOD(A1:B3,INT(A1:B3))<> 0, ТО очистить содержимое?{/post}{/quote}  
Добрый вечер, Сергей! Рад видеть, что Вы занялись и VBA.  
Кстати, иногда удобно сочетать и то, и другое.  
 
В VBA есть аналоги функции ЦЕЛОЕ() это Int и Fix, они отличаются только отбрасыванием десятичных разрядов отрицательных чисел: Int(-2.1) = -3, Fix(-2.1) = -2  
В данном случае можно воспользоваться ими  
If a(r, c) <> Int(a(r, c)) Then ...  
или  
If a(r, c) <> Fix(a(r, c)) Then ...  
 
Round я применил Round для перестраховки, потому что Int и Fix могут в 15-м значащем разряде глючить, хотя в данном случае и они должны работать корректно.  
 
В VBA есть и аналог функции ОСТАТ, это оператор MOD  
Например, формуле =ОСТАТ(5;2) соответствует VBA код: 5 Mod 2  
 
Но есть существенные отличия:  
 
1. ОСТАТ работает со всем диапазонов чисел, а Mod - только в пределах Long, то есть, от 2147483648 до 2147483647. Например, 3000000000 Mod 2 выдаст ошибку.  
 
2. Знак (плюс/минус) результата ОСТАТ определяется знаком второго аргумента, и не зависит от знака первого, а для Mod - наоборот.  
Например, =ОСТАТ(-5;2) = 1, =ОСТАТ(5;-2) = -1, =ОСТАТ(-5;-2) =-1  
Но: -5 Mod 2 = -1, 5 Mod -2 = -1, -5 Mod -2 = -1
 
По поводу ЕСЛИ =MOD(A1:B3,INT(A1:B3))<> 0, ТО очистить содержимое - такого непосредственно нет.  
 
Но можно либо циклом, как у меня, либо соединить формулы и код, о чем я уже упоминал.  
 
Здесь для диапазона A1:A4 как бы выполнится формула массива =ЕСЛИ(A1:A4=ЦЕЛОЕ(A1:A4);A1:A4;"")  
 
Sub Test1()  
 Range("A1:A4").Value = Evaluate("=IF(A1:A4=INT(A1:A4),A1:A4,"""")")  
End Sub  
 
То же самое, но для выделенных одним блоком ячеек:  
 
Sub Test2()  
 Dim a As String  
 a = Selection.Address  
 Selection.Value = Evaluate("=IF(" & a & "=INT(" & a & ")," & a & ","""")")  
End Sub  
 
Нужно учитывать, что пустые ячейки при этом будут заменены на ноль.
 
Для наглядности, а также если диапазон ячеек заранее известен можно вместо Evaluate("ExcelФормула") использовать [ExcelФормула]
Также с этой же целью можно вместо Range("АдресДиапазона").Value использовать [АдресДиапазона].Value
 
Тогда вместо Range("A1:A4").Value = Evaluate("=IF(A1:A4=INT(A1:A4),A1:A4,"""")")  
получится более наглядное: [A1:A4].Value = [=IF(A1:A4=INT(A1:A4),A1:A4,"")]
Недостатком такого подхода является немного большее время вычисления,  
но главное неудобство - невозможность программно менять адрес диапазона, в отличие от Evaluate (см. Test1 и Test2).  
 
Иногда .Value можно исключить: [A1:A4] = [=IF(A1:A4=INT(A1:A4),A1:A4,"")],
но лучше все же явно это прописывать, чтобы всегда гарантировать ожидаемый результат.
 
Если использован формат "Общий", т.е. целые числа отображаются без запятой, а дробные с запятой, то можно так:  
 
Sub bb()  
Dim c  
For Each c In Selection  
   If c.Text Like "*,*" Then c.ClearContents  
Next  
End Sub
 
Алексей, рискованно это.  
Введите в новой книге в какую-нибудь ячейку с общим форматом число 123456789.87 (для руской локализации - запятая вместо точки).  
У меня при Arial 10 отобразилось 123456790  ;-)
 
Владимир, спасибо большое, буду изучать!
Страницы: 1
Читают тему
Наверх