Методические указания и задания. Логические операторы VBA Операторы языка vba

знак название Описание
= Равно Возвращает True если левый и правый операнды равны. Обратите внимание, что это перегрузка оператора присваивания.
<> Не равен Возвращает True если левый и правый операнды не равны.
> Лучше чем Возвращает True если левый операнд больше правого операнда.
< Меньше, чем Возвращает True если левый операнд меньше правого операнда.
>= Больше или равно Возвращает True если если левый операнд больше или равен правому операнду.
<= Меньше или равно Возвращает True если левый операнд меньше или равен правому операнду.
Is Справочный капитал Возвращает значение True если ссылка на левый объект - это тот же экземпляр, что и ссылка на правый объект. Он также может использоваться с Nothing (ссылка на нулевой объект) с обеих сторон. Примечание. Оператор Is попытается принудить оба операнда к Object перед выполнением сравнения. Если какая-либо сторона является примитивным типом или Variant , который не содержит объект (либо не-объектный подтип, либо vtEmpty), сравнение приведет к ошибке времени выполнения 424 - «Требуется объект». Если любой операнд принадлежит другому интерфейсу одного и того же объекта, сравнение вернет True . Если вам нужно проверить справедливость как экземпляра, так и интерфейса, ObjPtr(left) = ObjPtr(right) используйте ObjPtr(left) = ObjPtr(right) .

Заметки

Синтаксис VBA позволяет «цепочки» операторов сравнения, но в целом эти конструкции следует избегать. Сравнение всегда выполняется слева направо только на 2 операндах за раз, и каждое сравнение приводит к Boolean . Например, выражение...

A = 2: b = 1: c = 0 expr = a > b > c

Может быть прочитан в некоторых контекстах как проверка того, является ли b между a и c . В VBA это оценивается следующим образом:

A = 2: b = 1: c = 0 expr = a > b > c expr = (2 > 1) > 0 expr = True > 0 expr = -1 > 0 "CInt(True) = -1 expr = False

Любой оператор сравнения, кроме Is использоваться с Object в качестве операнда будет выполняться на возвращаемом значении Object «s члена по умолчанию . Если объект не имеет члена по умолчанию, сравнение приведет к ошибке времени выполнения 438 - «Объект не поддерживает его свойство или метод».

Если Object не инициализирован, сравнение приведет к ошибке времени выполнения 91 - «Объектная переменная или С заблокированной переменной блока».

Если литерал Nothing используется с любым оператором сравнения, отличным от Is , это приведет к ошибке компиляции - «Недопустимое использование объекта».

Если Object по умолчанию Object является другой Object , VBA будет постоянно вызывать элемент по умолчанию каждого последующего возвращаемого значения до тех пор, пока не будет возвращен примитивный тип или не будет поднята ошибка. Например, предположим, что у SomeClass есть член по умолчанию Value , который является экземпляром ChildClass с членом ChildValue по ChildValue . Сравнение...

Set x = New SomeClass Debug.Print x > 42

Будет оцениваться как:

Set x = New SomeClass Debug.Print x.Value.ChildValue > 42

Если либо операнд является числовым, а другой операндом является String или Variant подтипа String , будет выполнено числовое сравнение. В этом случае, если String не может быть отнесено к числу, результатом сравнения будет ошибка времени выполнения 13 - «Несоответствие типа».

Если оба операнда представляют собой String или Variant подтипа String , сравнение строк будет выполняться на основе параметра сравнения параметров модуля кода. Эти сравнения выполняются по характеру по характеру. Обратите внимание, что символьное представление String содержащей число, не совпадает с сопоставлением числовых значений:

Public Sub Example() Dim left As Variant Dim right As Variant left = "42" right = "5" Debug.Print left > right "Prints False Debug.Print Val(left) > Val(right) "Prints True End Sub

По этой причине убедитесь, что переменные String или Variant передаются в числа перед выполнением численных сравнений неравенства.

Если один из операндов - это Date , то числовое сравнение по базовому двойному значению будет выполняться, если другой операнд является числовым или может быть преобразован в числовой тип.

Если другой операнд представляет собой String или Variant подтипа String который может быть перенесен в Date с использованием текущего языкового стандарта, String будет передана в Date . Если он не может быть применен к Date в текущей локали, результатом сравнения будет ошибка времени выполнения 13 - «Несоответствие типа».

Следует соблюдать осторожность при сравнении значений Double или Single и Booleans . В отличие от других числовых типов ненулевые значения нельзя считать True из-за поведения VBA в продвижении типа данных сравнения с использованием числа с плавающей точкой в Double:

Public Sub Example() Dim Test As Double Test = 42 Debug.Print CBool(Test) "Prints True. "True is promoted to Double - Test is not cast to Boolean Debug.Print Test = True "Prints False "With explicit casts: Debug.Print CBool(Test) = True "Prints True Debug.Print CDbl(-1) = CDbl(True) "Prints True End Sub

Эти операторы сравнивают два выражения для определения равны ли они, и если нет то, как они отличаются. Is , IsNot и Like детально обсуждаются на отдельных страницах справки. Отношения операторов сравнения обсуждаются на этой странице.

Result = expression1 comparisonoperator expression2 result = object1 object2 result = string Like pattern

result
Обязательный. Результатом является значение Boolean , представляющее результат сравнения.

expression
Обязательный. Произвольное выражение.

comparisonoperator
Обязательный. Любой оператор сравнения отношения.

object1 , object2
Обязательный. Имя любого ссылочного объекта.

string
Обязательный. Произвольное выражение типа String .

pattern
Обязательный. Любое выражение String или диапазон символов.

В следующей таблице приводится список операторов сравнения и условий, определяющих, является ли result True или False .

Примечание

При сравнении строк строковые выражения вычисляются на основе их алфавитного порядка сортировки, который зависит от параметра Option Compare .

Option Compare Binary задает метод сравнения строк на основе порядка сортировки, определяемого внутренним двоичным представлением символов. Порядок сортировки определяется кодовой страницей. В следующем примере показан типичный порядок двоичной сортировки.

A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø

Option Compare Text задает метод сравнения строк на основе порядка сортировки текста (без учета регистра), определяемого региональными установками приложения. При установке Option Compare Text и сортировке символов в предыдущем примере применяется следующий текстовый порядок сортировки:

(A=a) < (À= à) < (B=b) < (E=e) < (Ê= ê) < (Ø = ø) < (Z=z)

Зависимость от языкового стандарта

При установке Option Compare Text результат сравнения строк может зависеть от языкового стандарта, в котором выполняется приложение. Два символа в одном языковом стандарте могут считаться равными, а в другом нет. При использовании сравнения строк для принятия важных решений, например разрешить ли попытку входа в систему, следует учитывать чувствительность к языковым стандартам. Рассмотрите возможность установки Option Compare Binary или вызова , который учитывает языковой стандарт.

Использование операторов сравнения с выражениями Object не допускается при Option Strict On . При Option Strict Off и либо выражение expression1 , либо expression2 является Object , типы времени выполнения определяют, как они будут сравниваться. В следующей таблице показано сравнение выражений и результаты сравнения в зависимости от типа операндов, определяемых во время выполнения:

При числовом сравнении Nothing приравнивается к 0. При сравнении строк Nothing обрабатывается как "" (пустая строка).

Операторы сравнения (< . <= , > , >= , = , <>) могут быть перегружены ; это означает, что класс или структура могут переопределить их поведение, когда операнд имеет тип этого класса или структуры. Если ваш код использует эти операторы для такого класса или структуры, убедитесь, что вы понимаете его переопределенное поведение. Дополнительные сведения см. в разделе

Логические операторы VBA используются для объединения результатов отдельных логических выражений, чтобы создать сложные критерии для принятия решений в процедуре (таблица Б.3).

Таблица Б.3 – Логические операторы VBA

Логический

Синтаксис

Имя/Описание

оператор

El And E2

Конъюнкция . True, если оба Е1 и Е2

имеют значение True, иначе – False

El Or E2

Дизъюнкция . True, если одно выра-

жение или оба (Е1 и Е2) являются

равными True; иначе – False

Not El

Отрицание . True, если Е1 имеет зна-

чение False; False, если El является

равным True

El Xor E2

Исключение . True, если Е1 и Е2

имеют разные значения; иначе –

El Eqv E2

Эквивалентность . True,если Е1 име-

ет то же самое значение, что и Е2;

иначе – False

El Imp E2

Импликация . False, когда Е1 является

равным True и Е2 равно False; иначе

True.

Операнды Е в этой таблице представляет собой любое допустимое выражение с результатом типа Boolean, такое как операция сравнения.

Приоритеты выполнения операций при вычислении сложных выражений

Сложное (составное) выражение (complex expression) – это любое выражение, образованное из двух или более выражений. В таблице Б.4 собраны операции по группам в порядке убывания приоритета, то есть чем ниже расположена группа, тем позже выполняются указанные в ней операции. Для изменения этого порядка применяются круглые скобки. Операции одного уровня выполняются слева направо в том порядке, в котором они записаны в выражении.

Таблица Б.4 – Приоритеты операций VBA

Оператор

Комментарии

Возведение в степень, наивысший приоритет

Унарный минус - изменение знака числа

Умножение и деление имеют равные приоритеты; они вы-

Деление нацело

Остаток от деления нацело

Сложение и вычитание имеют равный приоритет; они вы-

числяются по мере появления в выражении слева направо

Всякая конкатенация строк выполняется после любых

арифметических операций в выражении и перед любыми

операциями сравнения или логическими операциями

<, <=, >, >=,

Все операторы сравнения имеют равные приоритеты и вы-

числяются по мере появления в выражении слева направо.

Используйте круглые скобки для группирования операто-

ров сравнения в выражениях

Логические

Not And Or Xor Eqv Im p – имеют низший приоритет

операторы

Приложение В Математические функции VBA

VBA предоставляет стандартный набор математических функций приведенный в таблице В.1.

Таблица B.1 – Математические функции VBA

Возвращает / действие

Возвращает абсолютное значение N

Косинус угла N, где N – это угол, измеренный в ра-

Возвращает синус угла; N – это угол, измеренный в

радианах

Возвращает тангенс угла; N – угол в радианах

Возвращает арктангенс N как угол в радианах

Возвращает константу е, возведенную в степень N (е –

это основание натуральных логарифмов и она (при-

близительно) равна 2,718282

Возвращает целую часть N. Fix не округляет число, а

отрицательным, Fix возвращает ближайшее отрица-

тельное целое большее, чем или равное N

Возвращает целую часть N. Int не округляет число, а

отбрасывает любую дробную часть. Если N является

отрицательным, Int возвращает ближайшее отрица-

тельное целое меньшее, чем или равное N

Возвращает натуральный логарифм N

Возвращает случайное число; аргумент является не-

обязательным. Используйте функцию Rnd только

после инициализации VBA-генератора случайных чи-

сел оператором Randomize

Возвращает знак числа: –1, если N – отрицательное;

1, если N –положительное; 0, если N равно 0

Возвращает корень квадратный из N. VBA отображает

ошибку исполнения, если N – отрицательное

Операнд N означает любое численное выражение? допустимое в

Аргумент тригонометрических функции (синуса, косинуса и тангенса) задается в радианах, а не в градусах. Обратная тригонометрическая функция A t n (x ) возвращает в программу значение угла в радианах от -π/2 до π/2, тангенс которого равен значению арифметического выражения х .

Связь между радианной и градусной мерами угла выражается через иррациональное число π ≈ 3,14159265358979323846.

Радианы=

Градусы× π

Градусы=

Радианы× 180

Для перевода градусов в радианы можно также использовать встроенную функцию Excel - Application.Radians(x ), где x – угол, за-

данный в радианах.

Для получения числового значения константы π с точностью 15 цифр мантиссы можно использовать встроенную функцию Excel Application.Pi(), либо функцию VBA арктангенс

Pi= Application.Pi() либо Pi=4*Atn(1)

Примеры записи тригонометрических функций

При написании кода VBA в Excel набор встроенных операторов используют на каждом шагу. Эти операторы делятся на математические, строковые, операторы сравнения и логические. Далее мы подробно рассмотрим каждую группу операторов.

Математические операторы

Основные математические операторы VBA перечислены в таблице ниже.

В правом столбце таблицы указан приоритет операторов, принятый по умолчанию при отсутствии скобок. Добавляя в выражение скобки, можно изменять порядок выполнения операторов VBA по своему желанию.

Строковые операторы

Основной строковый оператор в Excel VBA – это оператор конкатенации & (слияние):

Операторы сравнения

Операторы сравнения используются для сравнения двух чисел или строк и возвращают логическое значение типа Boolean (True или False). Основные операторы сравнения Excel VBA перечислены в этой таблице:

Логические операторы

Логические операторы, как и операторы сравнения, возвращают логическое значение типа Boolean (True или False). Основные логические операторы Excel VBA перечислены в таблице ниже:

В приведённой выше таблице перечислены не все логические операторы, доступные в VBA. Полный список логических операторов можно найти на сайте Visual Basic Developer Center .

Встроенные функции

В VBA доступно множество встроенных функций, которые могут быть использованы при написании кода. Ниже перечислены некоторые из наиболее часто используемых:

Функция Действие
Abs Возвращает абсолютную величину заданного числа.
  • Abs(-20) возвращает значение 20;
  • Abs(20) возвращает значение 20.
Chr Возвращает символ ANSI, соответствующий числовому значению параметра.
  • Chr(10) возвращает перенос строки;
  • Chr(97) возвращает символ a .
Date Возвращает текущую системную дату.
DateAdd Добавляет определённый временной интервал к заданной дате. Синтаксис функции:

DateAdd(интервал , число , дата )

Где аргумент интервал определяет тип временного интервала, добавляемого к заданной дате в количестве, указанном в аргументе число .

Аргумент интервал может принимать одно из следующих значений:

  • DateAdd(“d”, 32, “01/01/2015”) добавляет 32 дня к дате 01/01/2015 и, таким образом, возвращает дату 02/02/2015.
  • DateAdd(“ww”, 36, “01/01/2015”) добавляет 36 недель к дате 01/01/2015 и возвращает дату 09/09/2015.
DateDiff Вычисляет количество определённых временных интервалов между двумя заданными датами.
  • DateDiff(“d”, “01/01/2015”, “02/02/2015”) вычисляет количество дней между датами 01/01/2015 и 02/02/2015, возвращает результат 32.
  • DateDiff(“ww”, “01/01/2015”, “03/03/2016”) вычисляет количество недель между датами 01/01/2015 и 03/03/2016, возвращает результат 61.
Day Возвращает целое число, соответствующее дню месяца в заданной дате.

Пример: Day(“29/01/2015”) возвращает число 29.

Hour Возвращает целое число, соответствующее количеству часов в заданном времени.

Пример: Hour(“22:45:00”) возвращает число 22.

InStr Принимает в качестве аргументов целое число и две строки. Возвращает позицию вхождения второй строки внутри первой, начиная поиск с позиции, заданной целым числом.
  • InStr(1, “Вот искомое слово”, “слово”) возвращает число 13.
  • InStr(14, “Вот искомое слово, а вот еще искомое слово”, “слово”) возвращает число 38.

Примечание: Аргумент-число может быть не задан, в таком случае поиск начинается с первого символа строки, заданной во втором аргументе функции.

Int Возвращает целую часть заданного числа.

Пример: Int(5.79) возвращает результат 5.

Isdate Возвращает True , если заданное значение является датой, или False – если датой не является.
  • IsDate(“01/01/2015”) возвращает True ;
  • IsDate(100) возвращает False .
IsError Возвращает True , если заданное значение является ошибкой, или False – если ошибкой не является.
IsMissing В качестве аргумента функции передаётся имя необязательного аргумента процедуры. IsMissing возвращает True , если для рассматриваемого аргумента процедуры не передано значение.
IsNumeric Возвращает True , если заданное значение может быть рассмотрено как число, в противном случае возвращает False .
Left Возвращает заданное количество символов от начала переданной строки. Синтаксис функции вот такой:

Left(строка , длина )

где строка – это исходная строка, а длина – количество возвращаемых символов, считая от начала строки.

  • Left(“абвгдежзиклмн”, 4) возвращает строку “абвг”;
  • Left(“абвгдежзиклмн”, 1) возвращает строку “а”.
Len Возвращает количество символов в строке.

Пример: Len(“абвгдеж”) возвращает число 7.

Month Возвращает целое число, соответствующее месяцу в заданной дате.

Пример: Month(“29/01/2015”) возвращает значение 1.

Mid Возвращает заданное количество символов из середины переданной строки. Синтаксис функции:

Mid(строка , начало , длина )

где строка – это исходная строка, начало – позиция начала извлекаемой строки, длина – количество символов, которые требуется извлечь.

  • Mid(“абвгдежзиклмн”, 4, 5) возвращает строку “гдежз”;
  • Mid(“абвгдежзиклмн”, 10, 2) возвращает строку “кл”.
Minute Возвращает целое число, соответствующее количеству минут в заданном времени.Пример: Minute(“22:45:15”) возвращает значение 45.
Now Возвращает текущую системную дату и время.
Right Возвращает заданное количество символов от конца переданной строки. Синтаксис функции:

Right(строка , длина )

Где строка – это исходная строка, а длина – это количество символов, которые надо извлечь, считая от конца заданной строки.

  • Right(“абвгдежзиклмн”, 4) возвращает строку “клмн”;
  • Right(“абвгдежзиклмн”, 1) возвращает строку “н”.
Second Возвращает целое число, соответствующее количеству секунд в заданном времени.

Пример: Second(“22:45:15”) возвращает значение 15.

Sqr Возвращает квадратный корень числовой величины, переданной в аргументе.
  • Sqr(4) возвращает значение 2;
  • Sqr(16) возвращает значение 4.
Time Возвращает текущее системное время.
Ubound Возвращает верхний индекс измерения заданного массива.

Примечание: Для многомерных массивов в качестве необязательного аргумента может быть указано, индекс какого именно измерения нужо возвратить. Если не указано, то по умолчанию равно 1.

Инструкции (или операторы) языка – это программные единицы, выполняющие какие-то действия или описывающие данные.

В состав оператора входят одно или несколько ключевых слов, а также, возможно, параметры. Несколько операторов, расположенных в одной программной строке, отделяются друг от друга двоеточием. Если оператор слишком длинный, можно разбить его на несколько строк, используя для переноса символ подчеркивания _.

О ператор присвоения

Оператор присвоения используется для присвоения нового значения переменной в ходе выполнения программы. Знак присвоения «=».

Например , оператор:

x = Sqr(5 + Tan(1.8) ^ 2)

присваивает переменной х значение выражения . В результате вычисления выражения, записанного в правой части, получим вещественное число. Но значение, которое будет присвоено переменной х, зависит от того, как был описан тип этой переменной. Так, если переменная х имеет тип Single, ей будет присвоен результат 4,834464 , если Double, то 4,83446368725481, а если Integer, то 5.

Тип данных переменной х должен быть совместим с типом данных этого выражения. Кроме неявного преобразования из одного типа в другой при присвоении, в языке Visual Basic предусмотрена возможность преобразования типов с помощью функций. Например, функция CDbl преобразует данные к типу Double, CInt – к типу Integer, Clng – к типу Long, CSng – к типу Single, CStr – к типу String и т. д.

Функции CInt и Clng выполняют округление результата. При этом если дробная часть числа равна 0,5, округление производится до ближайшего четного числа.

Оператор присвоения позволяет не только присвоить значение переменной, но и задать значения свойств объектов VBA. Например, оператор

Rows("1:1").Font. Bold = True

делает полужирным шрифт в первой строке рабочего листа.

ПЕРЕНОС СТРОКИ

Комбинация <Пробел> + <Знак подчеркивания> в конце строки обеспечивает то, что последующая строка является продолжением предыдущей. При этом надо помнить что:

§ Нельзя разбивать переносом строковые константы

§ Допустимо не более семи продолжений одной и той же строки

§ Сама строка не может содержать более 1024 символов

Пример.

Некорректный перенос Корректный перенос

Строка = "Visual Basic for _ Строка = "Visual Basic" _

Applications" & "for Applications "

КОММЕНТАРИИ

Текст, следующий в программе за символом (") вплоть до конца строки игнорируется компилятором и является комментарием. С помощью комментариев добавляются пояснения и описания к программе. Комментарии полезны при отладке программы: они позволяют временно отключить строки программы при отладке.

Условный оператор

Условный оператор выполняет определенные инструкции (операторы) в зависимости от значения выражения условия. Блок-схема проверки условия имеет вид:

Рис. 1. Ветвление может быть неполным (такую структуру называют еще обход).

Рис. 2. Условный оператор имеет две формы синтаксиса: строчную и блочную.

Строчная форма

If условие Then [операторы­_если_истина ]

Алгоритм, представленный на рис. 1, в строчной форме будет записан в виде

If условие Then операторы­_если_истина Else операторы­_если_ложь

Рисунку 2 соответствует запись

If условие Then операторы­_если_истина

Рисунку 3 соответствует запись

If условие Then Else операторы­_если_ложь

Блочная форма

If условие-1 Then

[операторы­_если условие–1_истина ]

[операторы­_если_ все_условия_ложь ]]

Условия, перечисленные в частях If и ElseIf, представляют собой выражения отношения или логические выражения. При выполнении одного из условий выполняются инструкции, следующие за соответствующим ему ключевым словом Then, а остальные инструкции игнорируются (т. е. дальнейшие проверки не выполняются и управление передается оператору, следующему за End If). Если ни одно из логических условий не равно истине, то выполняются операторы­_если_ все_предыдущие_условия_ложь , либо, если эта часть опущена, управление передается строке программы, следующей после условного оператора.

Блочная форма оператора If более предпочтительна, если:

При выполнении или невыполнении условия выполняется несколько операторов (строчную форму в этом случае тоже можно использовать, но строка будет слишком длинной, а программа – менее понятной);

Последовательно проверяется несколько условий, и при выполнении очередного условия проверять последующие условия нецелесообразно (для этого и используется ключевое слово ElseIf).

Пример

Фирма предоставляет скидки оптовым покупателям.

По известному объему заказа надо определить его стоимость.

Для вычисления стоимости заказа используем функцию:

Public Function Стоимость_заказа(Количество As Long) As Double

If Количество <= 999 Then

Стоимость_заказа = Количество * 5

ElseIf Количество <= 1999 Then

Стоимость_заказа = Количество * 4.8

Стоимость_заказа = Количество * 4.75

В данном случае можно было использовать и строчную форму оператора IF:

Public Function Стоимость_заказа1(Количество As Long) As Double

If Количество <= 999 Then Стоимость_заказа1 = Количество * 5

If Количество >= 1000 And Количество <= 1999 Then Стоимость_­ заказа1 = Количество * 4.8

If Количество >= 2000 Then Стоимость_заказа1 = Количество * 4.75

Если не считать недостатками то, что строки длинноваты, и при любом объеме заказа последовательно выполняются все проверки (первая процедура при малых объемах заказа работает быстрее), то программа написана верно и, может быть, даже более наглядна.

Однако можно привести примеры, когда при выполнении (или невыполнении) одного из условий другие проверять просто нельзя.

Например , некоторые операторы должны выполняться при совместном выполнении условий: http://po-teme.com.ua/images/adIIIin/image014_e652e49476c6f0eb9cf40b68cc090828.gif" alt="" width="56" height="27 src=">. Если для проверки использовать оператор

If x>0 and y

то при отрицательном значении х возникнет ошибка при вызове функции sqr (под корнем отрицательное число).

Этой ошибки можно избежать, если использовать конструкцию

If x > 0 Then If y < Sqr(x) Then

В последней форме записи если есть ключевое слово Else, то оно относится к последнему оператору If.

Оператор выбора

Select Case выражение

[инструкции_ else ]]

Параметр выражение – любое числовое или строковое выражение. Вместо вычисления логического условия выполняется сравнение значения выражения с каждой из величин, заданных параметром список_выражений- n .

Величины для сравнения, входящие в список_выражений-n , могут быть заданы в виде:

– значения;

– диапазона значений в виде начальное_значение To конечное_значение ;

– выражения сравнения в виде Is оператор_сравнения значение ;

– списка любых из перечисленных видов выражений (разделитель – запятая).

В инструкции может быть произвольное число блоков Case. Если ни одно из условий не является истинным, то выполняются инструкции блока Case Else.

Например, если условием является оценка выше тройки, то это условие можно записать: Case 4, 5 или Case Is >3 или Case Is >= 4 или Case 4 To 5.

Примечание. Ключевое слово Is можно не вводить, оно добавится само.

Пример

Рассмотренный выше пример с дисконтируемой ценой с помощью конструкции Select Case можно решить так:

Public Function Стоимость_заказа2(Количество As Long) As Double

Select Case Количество

Стоимость_заказа2 = Количество * 5

Case 1000 To 1999

Стоимость_заказа2 = Количество * 4.8

Case Is >= 2000

Стоимость_заказа2 = Количество * 4.75

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.