Ежегодная Международная Олимпиада по объектно-ориентированному программированию учетноаналитических задач для студентов ВУЗов Для чего студенту принимать участие в Олимпиаде по программированию? Постовалов Сергей Николаевич, Член жюри регионального тура доцент кафедры прикладной математики postovalov@ngs.ru Общие положения В Олимпиаде по программированию учетноаналитических задач могут принять участие студенты с 1-го по 5-й курс любого ВУЗа, получающие первое высшее образование. В качестве языка программирования участник использует встроенный язык прикладной системы "1С:Предприятие 8". Олимпиада проводится в два тура. Первый тур (заочный или региональный) проводится в январе марте, второй тур (очный) - в апреле 24-я олимпиада, второй тур Федорова Наталья, победитель регионального тура Олимпиады, г. Новосибирск Новосибирский государственный университет экономики и управления Победители 24-й олимпиады Абсолютный победитель - Шевченко Дмитрий Павлович, Дальневосточная государственная социально-гуманитарная академия Факультет математики и информатики, 5-й курс I место - Холостов Александр , г. Москва Финансовая академия при Правительстве Российской Федерации Факультет Математические методы в экономике и анализ рисков, 5-й курс II место - Наумов Сергей Валерьевич, г. Москва Национальный исследовательский ядерный университет «МИФИ» Экономико-аналитический институт, 5-й курс III место – Афанасьева Александра Викторовна, г.Москва Московский государственный технический университет имени Н.Э.Баумана Факультет информатики и системы управления, 6-й курс Тюкмаев Рустам Искандерович, г. Москва Московский государственный технический университет имени Н.Э.Баумана. Факультет робототехники и комплексной автоматизации, 5-й курс Сивин Алексей Юрьевич, г. Барнаул. Всероссийский заочный Финансово-экономический институт. Факультет менеджмента и маркетинга, 2-й курс Задание 2 тура 24-й Олимпиады по программированию учетно-аналитических задач в «1С:Предприятие 8» С 1 апреля 2010 г. организация переходит с ручного на автоматизированное ведение бухгалтерского учета. При учете основных средств организация применяет метод начисления амортизации способом «по сумме чисел лет срока полезного использования». В компьютерной программе на счетах 01 «Основные средства» и 02 «Амортизация ОС» организован пообъектный аналитический учет в разрезе элементов справочника «Основные средства». В учетную систему по каждому объекту ОС на дату начала ведения учета введены следующие данные: • первоначальная стоимость ОС - дебетовое сальдо счета 01 • накопленная сумма амортизации ОС на первое число месяца начала ведения автоматизированного учета - кредитовое сальдо счета 02 • оставшийся срок полезного использования в месяцах (включая первый месяц начала ведения учета) - реквизит справочника «Основные средства». Введя указанные данные учетные работники выяснили, что программа не сможет по этим данным производить начисление амортизации по объектам основных средств в течение оставшегося срока их полезного использования. Для последующего начисления амортизации необходимо ввести в программу: • год и месяц первого периода начисления амортизации, • полный срок полезного использования (в целых годах). Требуется создать отчет: Выбрать из информационной базы Основное средство ОС-0001 ОС-0002 ОС-0003 ОС-0004 ОС-0005 Первоначальная стоимость ОС Износ на дату начала ведения учета 1620000,00 1593750,00 4925907,00 3401221,50 120000,00 65250,00 1440000,00 1114000,00 600000,00 300000,00 Оставшийся срок полезного использования (мес) 7 37 30 48 37 рассчитать Первый период начисления амортизации месяц год 11 5 10 4 н/о 2002 2007 2008 2005 н/о Полный срок полезного использования (лет) 8 6 4 9 н/о 25-я олимпиада Региональный тур. Новосибирск • Организация торгует товарами в розницу в киоске. По результатам продаж за неделю продавцом киоска составляется отчет, в котором указывается список проданных товаров, цены, сумма продажи. Также к отчету прикладывается кассовая лента, в которой отражена полученная выручка. В процессе составления отчета (регистрации продаж в течение недели) возможны ошибки, и по итогам недели может оказаться, что сумма выручки больше итоговой суммой продаж по товарному отчету. Причина – ошибочно пропущена продажа одного или нескольких товаров. • Так как отчет надо сдавать уже сейчас, и времени на поиск ошибок нет, продавец согласен на «временное решение» просто добавить в отчет какие-нибудь товары, чтобы сошлась сумма. Требуется реализовать алгоритм, выполняющий «подгонку». Исходные данные • Учет ведется в информационной базе 1С в бухгалтерской подсистеме. Остатки товаров хранятся на счете 41 в разрезе Номенклатуры. Справочник «Номенклатура» содержит дополнительный реквизит «Цена продажи». По этой цене и реализуется товар (отражается в товарном отчете). Для отражения товарного отчета в системе предусмотрен документ «Продажа товаров», в котором указывается список товаров, количество, цена, сумма. Задача • Требуется реализовать отчет (обработку), показывающий, какие товары и в каком количестве надо добавить в выбранный документ «Продажа товаров», чтобы сошлась сумма. В форме отчета (обработки) выбирается документ «Продажа товаров» и вводится фактическая сумма выручки. На выходе отчет показывает таблицу товаров, добавляемых в документ. • При этом нельзя допускать, чтобы в документе «Продажа товаров» количество продаваемого товара оказалось больше, чем в момент продажи было на складе. • Если вариант подобрать не удается, вместо вывода таблицы надо оповестить пользователя об отсутствии решения. Если вариантов несколько, вывести первый найденный. • Добавлять можно только целое количество единиц товара. Остатки на складе (счет 41) Наименование Бахилы Кол-во Цена 1000 4 Ортопедическая подушка Фарма 10 1 650 Ортопедич. подушка стандартная 7 1 500 Ортопедич. подушка средняя 20 1 500 Матрас орт сегм. Пастер 1сп 5 2 480 Коврик массажный 3 290 Валик массажный 21 160 Шарик массажный 1 970 Бандаж коленный 12 750 Наколенник эластичный 15 945 Стельки ортопедические М 31 290 Стельки ортопедические Ж 7 390 Продажи киоска Наименование Бахилы Кол-во Цена Сумма 20 4 80 Ортопедическая подушка Фарма 1 1 650 1 650 Ортопедич. подушка стандартная 3 1 500 4 500 Ортопедич. подушка средняя 2 1 500 3 000 Матрас орт сегм. Пастер 1сп 2 2 480 4960 Коврик массажный 3 290 870 Шарик массажный 1 970 970 Бандаж коленный 2 750 1500 Итого 17530 Сумма выручки составляет 18500 руб, следовательно, в продажах не хватает товаров на 970 рублей. Вывод отчета (товары, которые надо добавить на сумму 970): Кол-во Цена Сумма Наименование Стельки ортопедические М 2 290 580 Стельки ортопедические Ж 1 390 390 Итого 970 Дополнение для тех, кто решил основную задачу • Решить задачу удаления части товаров из товарного отчета, в случае, когда сумма выручки меньше итоговой суммы продаж по товарному отчету. Решение • • // Сумма текущего товарного отчета СуммаТоварногоОтчета = Отчет.ДокументПродажи.Товары.Итог("Сумма"); • Недостаток = Отчет.СуммаВыручки СуммаТоварногоОтчета; • • Сообщить("Сумма товарного отчета: "+СуммаТоварногоОтчета); • Сообщить("Выручка: "+Отчет.СуммаВыручки); • Сообщить("Недостаток: "+Недостаток); Извлечение остатков Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ПроводкиОстатки.Субконто1 КАК Товар, ПроводкиОстатки.КоличествоОстатокДт ЕСТЬNULL(ПродажаТоваровТовары.Количество, 0) КАК Остаток, | ПроводкиОстатки.Субконто1.ЦенаПродажи КАК Цена |ИЗ | РегистрБухгалтерии.Проводки.Остатки(&Момент, Счет = &Счет41, , ) КАК ПроводкиОстатки | ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТоваров.Товары КАК ПродажаТоваровТовары | ПО ПроводкиОстатки.Субконто1 = ПродажаТоваровТовары.Номенклатура | |УПОРЯДОЧИТЬ ПО | Цена УБЫВ"; Выполнение запроса Запрос.УстановитьПараметр("Момент", Момент); Запрос.УстановитьПараметр("Ссылка", Отчет.ДокументПродажи); Запрос.УстановитьПараметр("Счет41", ПланыСчетов.Бухгалтерский.Товары); Результат = Запрос.Выполнить(); // Таблица с остатками Остатки = Результат.Выгрузить(); // Наша задача перебрать все варианты включения товаров в отчет так, чтобы сумма недостачи была // минимальной (в идеале - нулевой!) // Алгоритм переборный - рассматриваем все комбинации // Товары 1 2 3 ... к // Количество 1 0 0 0 // 2 0 0 0 // ... // М1 0 0 0 // 0 1 0 0 // // 1 ... 1 0 // M1 M2 M3 // к - количество товаров ... 0 Mк Проверяем остатки // к - количество товаров к=Остатки.Количество(); Если к = 0 Тогда Сообщить("Недостаточно остатков на складе!"); Возврат; КонецЕсли; Проверяем остатки // к - количество товаров к=Остатки.Количество(); Если к = 0 Тогда Сообщить("Недостаточно остатков на складе!"); Возврат; КонецЕсли; Проверяем остатки // M* - колиичество доступного остатка на складе М = Новый Массив (к); // Цены на товары Ц = Новый Массив (к); ТК = Новый Массив (к); // Текущая комбинация товаров для добавления в товарный отчет ЛК = Новый Массив (к); // Лучшая комбинация товаров для добавления в товарный отчет Макс = 0; // Максимальная сумма, меньшая суммы недостатка СуммаТоваровНаСкладе = 0; Для Н=0 По к-1 Цикл М[Н]=Остатки[Н].Остаток; Ц[Н]=Остатки[Н].Цена; ТК[Н]=0;ЛК[Н]=0; Если М[Н]*Ц[Н]>Недостаток Тогда М[Н]= Цел(Недостаток/Ц[Н]); // Ограничиваем использование данного товара суммой недостатка КонецЕсли; СуммаТоваровНаСкладе = СуммаТоваровНаСкладе+М[Н]*Ц[Н]; КонецЦикла; Проверяем остатки // Проверяем возможность решения задачи "в принципе" Если СуммаТоваровНаСкладе<Недостаток и СуммаТоварногоОтчета<Отчет.СуммаВыручк и Тогда Сообщить("Сумма товаров на складе меньше суммы недостатка. Решение невозможно!"); Возврат; КонецЕсли; Выход = Ложь; Рез = "Решение невозможно!"; Пока Не Выход Цикл Выход = Истина; Для Н=0 По к-1 Цикл Если ТК[Н]<М[Н] Тогда ТК[Н]=ТК[Н]+1; Выход = Ложь; Прервать; Иначе ТК[Н]=0; КонецЕсли; КонецЦикла; Сум = 0; Для Н=0 По к-1 Цикл Сум = Сум + ТК[Н]*Ц[Н]; КонецЦикла; Если Сум>Макс И Сум<=Недостаток Тогда Макс = Сум; Для Н=0 По к-1 Цикл ЛК[Н] = ТК[Н]; КонецЦикла; КонецЕсли; Если Макс = Недостаток Тогда Рез = "Решение найдено!"; Сообщить("Перебор закончен!"); Выход = Истина; КонецЕсли; КонецЦикла; Вывод результата // Выводим результат Отчет.Подгонка.Очистить(); Для Н=0 По к-1 Цикл Если ЛК[Н]<>0 Тогда Стр= Отчет.Подгонка.Добавить(); Стр.Товар = Остатки[Н].Товар; Стр.Количество = ЛК[Н]; Стр.Цена = Ц[Н]; Стр.Сумма = Стр.Количество*Стр.Цена; КонецЕсли; КонецЦикла; Дополнительная задача // берем товар со из товарного отчета для исключения Запрос.Текст = "ВЫБРАТЬ | ПродажаТоваровТовары.Номенклатура КАК Товар, | ПродажаТоваровТовары.Количество КАК Остаток, | ПродажаТоваровТовары.Цена КАК Цена |ИЗ | Документ.ПродажаТоваров.Товары КАК ПродажаТоваровТовары |ГДЕ | ПродажаТоваровТовары.Ссылка = &Ссылка | |УПОРЯДОЧИТЬ ПО | Цена УБЫВ"; Недостаток = - Недостаток; // Избыток!!!