Объявление внутренней переменной 2 страница
Модуль формы документа – запускается при открытии формы документа.
Модуль документа – запускается при проведении документа, при удалении документа, при снятии проведения.
Модуль формы журнала документа – запускается при вызове формы журнала.
Формат программного модуля
ПМ состоит из операторов и комментариев. Комментарий начинается с двойной наклонной черты (//). Оператор заканчивается символом точка с запятой (;). Операторы подразделяются на операторы объявления переменных и на исполняемые операторы.
Исполняемый оператор может иметь метку, являющейся точкой перехода в операторе Перейти.
Метка начинается с символа ~.
Пример:
~ метка А=В;
Структура программного модуля
ПМ состоит из следующих разделов:
ü раздел определения переменных;
ü раздел процедур и функций;
ü раздел основной программы.
Специальные символы, используемые в контексте модуля:
| – вертикальная черта в начале строки используется только в строковых константах – означает, что данная строка является продолжением предыдущей;
() – в круглые скобки заключается, список параметров методов, процедур и функций;
[] – в квадратные скобки заключается значение размерности массива;
“” – в кавычки заключаются строковые константы;
‘’ – в апострофы заключаются константы дат;
. – точка является разделителем в описаниях агрегатных типов данных.
Объявление переменных
Для объявления переменной используется следующий синтаксис:
Перем <Имя_перем> [<размерность>] [Экспорт]
Пример фрагмента модуля:
Перем Результат;
Перем Массив_Результатов [20];
Управляющие операторы
Условный оператор
Для условного оператора используется следующий синтаксис:
Если <логическое выражение> Тогда
// операторы;
[ИначеЕсли < логическое выражение > Тогда] // операторы;
[Иначе]
// операторы;
КонецЕсли;
Пример фрагмента модуля:
Если ДатаК < ДатаН Тогда
ДатаК = ДатаН;
ИначеЕсли ДатаК > ПолучитьДатуТА() Тогда
ДатаК = ПолучитьДатуТА();
КонецЕсли;
Если конечная дата меньше начальной, то переменной ДатаК присваивается значение начальной даты, в противном случае конечная дата сравнивается с результатом работы функции ПолучитьДатуТА() (функция возвращает дату точки актуальности) и, если условие выполняется, переменной ДатаК присваивается значение точки актуальности.
Оператор цикла Для
Для данного оператора цикла используется следующий синтаксис:
Для <имя перем> = <выражение1> По <выражение2> Цикл
// операторы;
КонецЦикла;
Пример фрагмента модуля:
Выв=СоздатьОбъект(“Текст”);
Выв.Открыть (“имя файла”);
Для i=1 по Выв.КоличествоСтрок() Цикл
Сообщить (Выв.ПолучитьСтроку(i));
КонецЦикла;
Пример демонстрирует вывод всех строк текста, содержащегося в объекте агрегатного типа Текст.
Оператор цикла Пока
Синтаксис оператора выглядит следующим образом:
Пока < логическое выражение > Цикл
// операторы;
КонецЦикла;
Циклическое повторение операторов, находящихся внутри конструкции, выполняется, пока логическое выражение – истина.
Пример использования цикла:
ВыбратьСтроки();
Пока ПолучитьСтроку()=1 Цикл
Регистр.Доставка.Товар=Товар;
Регистр.Доставка.Сумма=Сумма;
Регистр.Доставка.ДвижениеПриходВыполнить();
КонецЦикла;
Метод ВыбратьСтроки открывает выборку строк табличной части документа. В качестве логического выражения используется метод ПолучитьСтроку, который возвращает число 1, пока строки в выборке есть. Таким образом, для каждой табличной строки выполняются действия, связанные с занесением значений реквизитов Товар и Сумма в соответствующие параметры регистра Доставка.
Агрегатные типы данных
Агрегатные типы даны – это специализированные типы данных системы 1С: Предприятие. Суть этих типов – отражение объектов предметной области и способ работы с ними. Каждый агрегатный тип имеет набор атрибутов и методов. Понятие атрибута аналогично понятию свойства объекта в Visual Basic. Значения атрибутов можно читать и присваивать.
Методы – это те действия, которые могут выполняться над объектом (функции, определяющие поведение объекта).
Работа с объектом агрегатного типа определяется следующей последовательностью действий.
1. С помощью функции СоздатьОбъект создается объект агрегатного типа и какой-либо переменной присваивается ссылка на него.
2. Объект позиционируется на нужном элементе данных.
3. Проводятся манипуляции с объектом через вызовы методов и обращения к его атрибутам.
4. Если объект больше не нужен, он может быть отсоединен от переменной путем переприсваивания переменной какого-либо значения базового типа.
Позиционирование объекта на нужном элементе данных
Объект, созданный с помощью функции СоздатьОбъект, изначально не определен (не содержит никакого значения).
Для того чтобы начать с ним работать, его необходимо позиционировать – установить на конкретный элемент справочника или документа.
В случае позиционирования объекта типа Документ применяют один из следующих методов:
ü НайтиДокумент();
ü НайтиПоНомеру();
ü ПолучитьДокумент().
В случае позиционирования объекта типа Справочник применяют такие методы, как НайтиЭлемент(), НайтиПоКоду(), ПолучитьЭлемент().
Пример позиционирования объекта:
Процедура ОбработкаПроведения()
Спр=СоздатьОбъект("Справочник.Спонсоры");
ВыбратьСтроки();
Пока ПолучитьСтроку()=1 Цикл
Спр.НайтиЭлемент(Спонсор);
Спр.Адрес=Адрес;
Спр.Телефон=Телефон;
Спр.Записать();
КонецЦикла;
КонецПроцедуры
Процедура позволяет внести изменения в справочник Спонсоры с помощью документа Изменение данных (рис. 24).
Метод справочника НайтиЭлемент ищет в справочнике значение реквизита Спонсор, соответствующее значению, введенному в поле документа.
Рис. 24. Форма документа Изменение данных
Метод Записать позволяет обновить в справочнике значения адреса и телефона указанного спонсора.
Методы справочников
Рассмотрим некоторые методы справочников, которые наиболее часто используются в модулях форм и отчетов.
ТекущийЭлемент() – возвращает значение элемента справочника в целом как объекта. Метод используется для присвоения элемента какому-либо реквизиту.
Пример:
Пока СпрСотр.ПолучитьЭлемент()=1 Цикл
ТЭ=СпрСотр.ТекущийЭлемент();
Если ТЭ.ЭтоГруппа()=1 Тогда
Наз=ТЭ.Наименование;
КонецЦикла
Пример демонстрирует часть процедуры Сформировать, в которой организована выборка элементов справочника Сотрудники. Временной переменной ТЭ присваивается текущий элемент справочника, а затем проверяется на принадлежность к группе. Если элемент является группой, то переменной Наз присваивается наименование этой группы.
Выбрать(<Подсказка>, <ФормаСписка>) – вызывает диалоговое окно для выбора элемента и затем позиционирует справочник на выбранном элементе. Метод возвращает число 1, если элемент выбран, 0 – если не выбран.
Подсказка – текст заголовка окна диалога выбора.
ФормаСписка – идентификатор формы списка справочника. Если это значение пустое, то используется форма списка по умолчанию.
Пример:
Процедура Номера()
Ном=СоздатьОбъект("Справочник.Номера");
Ном.ИспользоватьВладельца(Абонент);
Если Ном.Выбрать("Выберите номер","")>0 тогда
НоваяСтрока();
Телефон=Ном.ТекущийЭлемент();
КонецЕсли;
КонецПроцедуры
В примере представлена процедура модуля формы. Процедура позволяет выбрать нужный элемент из формы списка подчиненного справочника Номера и присвоить значение реквизита справочника Наименование (основное представление справочника) реквизиту документа Телефон.
ВыбратьЭлементыПоРеквизиту(<имя реквизита>, <значение>, <режим иерархии>, <режим групп>) – открывает выборку элементов справочника по значению реквизита.
Режим иерархии задается числами (1 или 0):
1 – выбор элементов в соответствии с заранее заданным порядком (например, по возрастающему коду); 0 – выбор без учета иерархии.
Режим групп задается числами (1 или 0):
1 – выбор элементов среди групп справочника;
0 – выбор среди элементов справочника.
Важно! Для использования метода необходимо в окне свойств реквизита установить флажок Отбор по реквизиту.
Пример:
СпрСотр = СоздатьОбъект("Справочник.Сотрудники");
СпрСотр.ИспользоватьВладельца(ВыбКаф);
СпрСотр.ВыбратьЭлементыПоРеквизиту("Должность",ВыбДолж,0,0);
В примере представлен фрагмент процедуры Сформировать. Процедура выводит список сотрудников, работающих на выбранной должности выбранной кафедры. Для успешной работы метода ВыбратьЭлементыПоРеквизиту необходимо установить флажок Отбор по реквизиту в свойствах реквизита Должность справочника Сотрудники.
НайтиЭлемент(<Элемент>) – выполняет поиск элемента справочника по значению, заданному параметром <Элемент>. Метод используется только для объектов, созданных функцией СоздатьОбъект.
Новый() – позволяет добавить новый элемент в справочник.
Записать() – позволяет внести изменения в справочник.
Пример:
СпрСотр=СоздатьОбъект("Справочник.Сотрудники");
СпрСотр.НайтиЭлемент(Сотрудник);
СпрСотр.Адрес=Адрес;
СпрСотр.Записать();
Пример демонстрирует часть процедуры проведения документа, в котором отсутствует табличная часть. В справочнике Сотрудники ищется элемент (запись) со значением сотрудника, указанного в документе и обновляется значение реквизита Адрес.
Методы, применяемые для поиска элемента справочника:
ü НайтиЭлемент(<Элемент>);
ü НайтиПоКоду(<Код>);
ü НайтиПоНаименованию(<Наименование>);
ü НайтиПоРеквизиту (<Реквизит>, <Значение>).
В последнем случае необходимо, чтобы элементы справочника были отсортированы по этому реквизиту – в свойстве реквизита на вкладке Дополнительные необходимо установить флажок Сортировка.
Метод ПорядокНаименований() устанавливает режим выборки элементов справочника в порядке возрастания наименования элементов.
ПорядокКодов() – устанавливает режим выборки элементов справочника в порядке возрастания кодов элементов.
ЭтоГруппа() – проверяет принадлежность элемента к группе и возвращает значение 1, если текущий элемент справочника – группа.
Уровень() – определяет номер уровня текущего элемента справочника.
ИспользоватьВладельца(<Владелец>) – устанавливает элемент справочника-владельца, которому подчинен текущий подчиненный справочник. Параметр не является обязательным.
ВыбратьЭлементы() – открывает выборку элементов справочника. Метод возвращаетчисло 1, если в выборке есть хотя бы один элемент, и число 0, если в выборке нет ни одного элемента.
ПолучитьЭлемент() – позволяет получить из выборки следующий элемент справочника. Метод работает в паре с методом ВыбратьЭлементы().
Пример:
СпрСотр=СоздатьОбъект("Справочник.Сотрудники");
СпрСотр.ПорядокНаименований();
СпрСотр.ИспользоватьВладельца(ВыбКаф);
СпрСотр.ВыбратьЭлементы();
Пока СпрСотр.ПолучитьЭлемент()=1 Цикл
Пример демонстрирует часть процедуры Сформировать. В справочнике Сотрудники выбираются элементы (записи о сотрудниках), относящиеся к кафедре, значение которой определяется переменной ВыбКаф. Элементы справочника сортируются в алфавитном порядке по реквизиту Наименование.
Методы документов
Рассмотрим некоторые методы документов, которые наиболее часто используются в модулях форм и отчетов.
ВыбратьСтроки() – открывает выборку строк многострочной части документа.
ПолучитьСтроку() – получает из выборки следующую строку табличной части документа. Метод возвращает число 1, если следующая строка выбрана успешно и число 0, если следующая строка документа не найдена.
НоваяСтрока() – позволяет добавить новую строку с очередным порядковым номером в многострочную часть документа.
УдалитьСтроку() – удаляет текущую строку из многострочной части документа.
КоличествоСтрок() – возвращает числовое значение – количество строк в документе.
УстановитьРеквизитСправочника(<элемент справочника>, <имя реквизита>, <значение>, <дата установки>, <имя типа>, <длина>, <точность> – записывает новое значение периодического реквизита справочника с привязкой к документу.
Пример:
ВыбратьСтроки();
Пока ПолучитьСтроку()=1 Цикл
УстановитьРеквизитСправочника(Товар, "Цена", НоваяЦена);
КонецЦикла;
Пример демонстрирует часть процедуры ОбработкаПроведения документа Изменение цен (рис. 25). Методы ВыбратьСтроки и ПолучитьСтроку позволяют осуществить выборку строк табличной части документа. Для каждой табличной строки документа выполняются действия, связанные с параметрами метода УстановитьРеквизитСправочника:
ü поиск элемента справочника Номенклатура, соответствующего значению реквизита документа Товар (тип – Справочник.Номенклатура);
ü в найденном элементе справочника значение реквизита Цена заменяется значением реквизита НоваяЦена из текущей строки документа.
Рис. 25. Форма документа Изменение цен товара
Итог(<ИмяРеквизита>) – возвращает итоговое значение реквизита табличной части документа.
Параметр <ИмяРеквизита> – строковое выражение, содержащее имя реквизита табличной части документа, для которого в конфигураторе установлено свойство Итог по колонке.
Модуль формы документа
Модуль формы документа может содержать процедуры, которые позволяют автоматизировать ввод данных в поля документа, при этом используется следующий алгоритм:
ü создается процедура с произвольным именем;
ü в процедуре используется оператор присваивания, левая часть которого соответствует имени реквизита документа, ввод значения которого необходимо автоматизировать;
ü в правой части оператора присваивания используется вычислительная формула или функция;
ü имя процедуры вводится в поле Формула на вкладке Дополнительно окна свойств реквизита документа, который необходимо связать с процедурой (рис. 26).
Рис. 26. Процедура Процент() выполняется после ввода значения в поле Сумма
Автоматизировать ввод значения реквизита документа можно, используя соответствующее значение реквизита справочника. Например, если в документе реквизит имеет тип Справочник, то в процедуре модуля формы правая часть оператора присваивания в общем виде будет выглядеть следующим образом:
ИмяРеквизитаДок-та.ИмяРеквизитаСправ-ка.ИмяМетода
Автоматический ввод значения реквизита документа рассмотрим на примере задачи Склад, в которой создан справочник Номенклатура.
В документе Приходная накладная присутствует реквизит Товар (тип Справочник. Номенклатура). Для автоматического ввода значения цены выбранного товара в модуле формы документа в соответствующей процедуре используется следующий оператор присваивания:
Цена = Товар.Цена
Если реквизит справочника периодический (значение реквизита привязывается к дате изменения значения), то дополнительно используется метод Получить(ДатаДок), который позволяет получить значение цены на дату документа.
Цена = Товар.ЦенаП.Получить(ДатаДок)
Модуль документа
Модуль документа содержит процедуру проведения документа. При проведении документа информация, содержащаяся в документе, заносится в базу данных (справочники или регистры), т. е. с помощью документов происходит обновление базы данных.
Пример:
Процедура ОбработкаПроведения()
СпрСотр=СоздатьОбъект("Справочник.Сотрудники");
СпрСотр.НайтиЭлемент(Сотрудник);
СпрСотр.Отдел=ОтделПосле;
СпрСотр.Записать();
КонецПроцедуры
Пример демонстрирует, как происходит изменение информации в справочнике Сотрудники при проведении документа Перемещение (рис. 27).
В справочнике Сотрудники с помощью метода НайтиЭлемент выполняется поиск конкретного элемента, определяемого значением реквизита документа Сотрудник. Затем в реквизит справочника Отдел заносится значение реквизита документа ОтделПосле. Метод справочника Записать фиксирует изменение данных в справочнике.
Рис. 27. Форма документа Перемещение
В модуле документа, содержащего табличную часть, ввод данных в механизмы хранения (справочник или регистр) выполняется в цикле.
Пример:
Процедура ОбработкаПроведения()
ВыбратьСтроки();
Пока ПолучитьСтроку()=1 Цикл
Регистр.Остатки.Товар = Товар;
Регистр.Остатки.Количество = Количество;
Регистр.Остатки.ДвижениеПриходВыполнить();
КонецЦикла;
КонецПроцедуры
Пример демонстрирует, как происходит изменение информации в регистре Остатки при проведении документа Приход товара (рис. 28).
Рис. 28. Форма документа “Приход товара”
Данные в регистр Остатки заносятся в цикле. Значения поля Товар документа Приход товара заносятся в измерение регистра Товар, а значения поля Количество – в ресурс регистра Количество.
Метод регистра ДвижениеПриходВыполнить() записывает данные в регистр остатков со знаком плюс.
В модулях документов при записи данных в регистры могут использоваться также методы: ДвижениеРасходВыполнить() – записывает данные в регистр остатков со знаком минус, ДвижениеВыполнить() – записывает данные в оборотный регистр.
Создание модуля отчета
Модуль отчета содержит процедуру Сформировать, связанную с одноименной кнопкой в диалоге отчета. При создании отчета (подведении итогов) данные могут выбираться из справочников, из документов или из регистров. Удобнее всего выбирать данные с помощью запросов, так как запросы позволяют использовать вычислительные функции. Поэтому, как правило, при создании отчетов пользуются следующим алгоритмом.
1. Создание запроса.
2. Присвоение результатов выборки и вычислительных функций временным переменным.
3. Создание шаблона таблицы с использованием имен временных переменных.
4. Вывод таблицы на экран или печать.
Создание запросов
Запросы в компоненте “Оперативный учет” могут создаваться к документам, справочникам и регистрам. Запрос в системе 1С: Предприятие относится к агрегатному типу данных и создается только программно. При работе с запросами используется следующая последовательность действий:
ü создается новый объект с помощью функции СоздатьОбъект (в качестве параметра функции используется ключевое слово Запрос);
ü создается текст запроса с использованием языка запросов;
ü текст описания запроса передается методу Выполнить в качестве параметра для создания временного набора данных (выборки), который будет использоваться в отчете;
ü формируется таблица вывода отчета.
Ниже представлен пример отчета, который выводит список сотрудников, работающих на должности, определяемой переменной ВыбДолж (тип – Справочник.Должности).
Отчет формируется при выполнении процедуры Сформировать, которая запускается по нажатии одноименной кнопки в форме отчета (рис. 29).
Рис. 29. Форма отчета (диалог)
Пример:
Процедура Сформировать()
Запрос1 = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|Сотр= Справочник.Сотрудники.Наименование;
|Долж = Справочник.Сотрудники.Должность;
|Группировка Сотр;
|Условие (Долж = ВыбДолж);
|Функция Колво = Счётчик();
|";
Запрос.Выполнить(ТекстЗапроса);
Рассмотрим на данном примере порядок работы с запросом.
1. Создается объект Запрос – переменной с произвольным именем (в примере используется имя Запрос1) присваивается ссылка на объект.
2. Формируется текст запроса – переменной с произвольным именем (в примере используется имя ТекстЗапроса) присваивается текстовая константа, каждая строка которой начинается с вертикальной черты. В данном примере текст запроса содержит следующие типы операторов языка запросов:
ü объявление внутренней переменной (объявляются переменные Сотр и Долж);
ü группировка – группируются записи справочника Сотрудники по реквизиту Сотрудник для возможности дальнейшего вывода списка сотрудников, работающих на выбранной должности;
ü условие – выбираются записи из справочника Сотрудники, должности которых соответствуют значению переменной ВыбДолж;
ü функция – вычисляется количество записей, соответствующих значению выбранной должности (в операторе Функция используется произвольное имя Колво).
3. Запрос запускается на выполнение с помощью метода Выполнить(ТекстЗапроса).
4. Результаты выполнения запроса сохраняются в тех переменных, которые были задействованы в тексте запроса (Сотр и Долж).
5. Для вывода результатов выборки создается объект Таблица и организуется циклическая обработка сформированной выборки с целью получения требуемого отчета.
Продолжение процедуры Сформировать:
Таб = CоздатьОбъект("Таблица");
Таб.ВывестиСекцию("Все<");
Пока Запрос.Группировка("Сотр")=1 Цикл
К = Запрос.Сотр;
К1=Запрос.Код;
Таб.ВывестиСекцию("Сотр");
КонецЦикла;
Таб.ВывестиСекцию("Все>");
Таб.Показать();
КонецПроцедуры
6. Ячейки таблицы могут содержать данные трех типов (тип выбирается в окне свойств ячейки):
ü текст – ячейка содержит только текстовые данные;
ü выражение – ячейка содержит имя переменной;
ü шаблон – ячейка содержит текстовые данные и имя переменной, заключенное в квадратные скобки (рис. 30).
Рис. 30. Окно свойств ячейки таблицы вывода
Если имена переменных берутся из текста запроса, то ячейки заполняются с использованием синтаксиса: Запрос.ИмяПеременной. (рис. 31).
Рис. 31. Таблица вывода результатов запроса
Можно добавить в процедуру операторы присваивания временным переменным с произвольными именами (в нашем примере К и К1) результатов выполнения запроса:
К = Запрос.Сотр; К1=Запрос.Код
В этом случае ячейки таблицы должны содержать имена временных переменных (рис. 32).
Рис. 32. Таблица вывода результатов запроса
Отчеты, соответствующие таблицам, представленным на рис. 31 и рис. 32, будут выглядеть одинаково (рис. 33).
Рис. 33. Вид готового отчета
Операторы языка запросов
Рассмотрим некоторые операторы, которые наиболее часто используются в тексте запросов.
Объявление внутренней переменной
Внутренние переменные используются в тексте запроса для образования ссылок на объекты конфигурации, чтобы использовать их при построении таких операторов запроса, как Группировка, Функция, Условие.
Это может быть ссылка на реквизит справочника, например:
Долж = Справочник.Сотрудники.Должность, или ссылка на параметр регистра: Кол=Регистр.КолЗап.Количество. Внутренняя переменная может ссылаться одновременно на нескольких объектов одного типа, например на два документа:
Товар = Документ.Перемещение.Товар, Документ.Расходная.Товар.
При выполнении группировки по переменной Товар будут выбраны все товары, встречающиеся в документах того и другого вида (Перемещение и Расходная).
Оператор Период С
Оператор Период С устанавливает интервал дат формирования запроса. Оператор используется при выборе данных из регистров или документов.
Пример:
ТекстЗапроса = "
|Период С ВыбДата По ВыбДата;
|Объект = Регистр.Суммы.Объект;
|Подрядчик = Регистр.Суммы.Подрядчик;
Если в описании запроса оператор Период С опущен, то интервал дат будет соответствовать точке актуальности итогов (ТА).
Оператор Группировка
Группировка устанавливает порядок выборки информации.
Общий синтаксис оператора Группировка:
Группировка <ИмяГруппировки>[Упорядочить по (<Порядок>)];
<ИмяГруппировки> – имя объявленной ранее внутренней переменной, по значению которой устанавливается порядок выборки.
Упорядочить по – необязательное ключевое слово, используемое для задания сортировки выбранных данных.
<Порядок> - используется только после ключевого слова Упорядочить по. Конкретизация внутренней переменной <ИмяГруппировки>, значение которой является параметром сортировки в сгруппированных записях (строках).
Пример:
ТЗ="
|Исполнитель = Регистр.КолЗап.Исполнитель;
|Альбом = Регистр.КолЗап.Альбом;
|Группировка Альбом Упорядочить по Альбом.Код;
В данном примере при выводе альбомов выбранного исполнителя список альбомов будет отсортирован по реквизиту Код.
Оператор Условие
Оператор Условие назначает условие включения информации в запрос.
Общий синтаксис: Условие <Логическое выражение>
<Логическое выражение> – имя объявленной ранее внутренней переменной, по значению которой устанавливается порядок выборки.
Оператор Функция
Общий синтаксис вычисляемой функции:
Функция <ИмяФункции> (<Параметр>);
<Параметр> – имя объявленной ранее внутренней переменной, значение которой используется как параметр встроенной функции. В таких функциях, как Сумма, Среднее, Максимум, Минимум в качестве параметра можно использовать арифметическое выражение. Имена некоторых наиболее часто используемых функций представлены в табл. 1.
Таблица 1
Имя функции | Выполняемое действие |
Сумма | Вычисляет сумму выбранных по запросу значений параметра |
Среднее | Вычисляет среднее из выбранных по запросу значений параметра |
Минимум (Максимум) | Вычисляет минимум (максимум) из выбранных по запросу значений параметра |
Счётчик | Подсчитывает количество записей, вошедших в выборку |
НачОст (КонОст)– | Вычисляет начальный (конечный) остаток для выбранных по запросу значений параметра |
Функции НачОст и КонОст можно использовать только с параметрами, указывающими на ресурсы регистров остатков. Одна из этих функций должна присутствовать обязательно в запросе к регистру остатков. Для обработки значений ресурсов оборотных регистров используется только функция Сумма.