////////// ОБЩИЕ КОМАНДЫ ВСЕХ ОБРАБОТЧИКОВ ////////////// // Master 16.12.2011 9:09:00 // Функция осуществляет подключение устройства. // // Параметры: // ОбъектДрайвера - <*> // - ОбъектДрайвера драйвера торгового оборудования. // // Возвращаемое значение: // <Булево> - Результат работы функции. // Функция ПодключитьУстройство(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Экспорт Результат = Истина; ПараметрыПодключения.Вставить("СерийныйНомерККМ", "0"); ПараметрыПодключения.Вставить("ИДУстройства", ""); ВыходныеПараметры = Новый Массив(); // Проверка параметров устройства Порт = Неопределено; Скорость = Неопределено; Таймаут = Неопределено; ПарольПользователя = Неопределено; ПарольАдминистратора = Неопределено; ОтменятьЧекПриПодключении = Неопределено; НаименованиеОплаты1 = Неопределено; НаименованиеОплаты2 = Неопределено; НомерСекции = Неопределено; // Master 15.12.2011 14:27:32 КодСимволаЧастичногоОтреза = Неопределено; ЖурналОперацийДрайвера = Неопределено; СовместимыеВерсии = Неопределено; Параметры.Свойство("Порт" , Порт); Параметры.Свойство("Скорость" , Скорость); Параметры.Свойство("Таймаут" , Таймаут); Параметры.Свойство("ПарольПользователя" , ПарольПользователя); Параметры.Свойство("ПарольАдминистратора" , ПарольАдминистратора); Параметры.Свойство("ОтменятьЧекПриПодключении" , ОтменятьЧекПриПодключении); Параметры.Свойство("НаименованиеОплаты1" , НаименованиеОплаты1); Параметры.Свойство("НаименованиеОплаты2" , НаименованиеОплаты2); Параметры.Свойство("НомерСекции" , НомерСекции); // Master 15.12.2011 14:27:22 Параметры.Свойство("КодСимволаЧастичногоОтреза", КодСимволаЧастичногоОтреза); Параметры.Свойство("ЖурналОперацийДрайвера" , ЖурналОперацийДрайвера); Если Порт = Неопределено Или Скорость = Неопределено Или Таймаут = Неопределено Или ПарольПользователя = Неопределено Или ПарольАдминистратора = Неопределено Или ОтменятьЧекПриПодключении = Неопределено Или НаименованиеОплаты1 = Неопределено Или НаименованиеОплаты2 = Неопределено Или НомерСекции = Неопределено // Master 15.12.2011 14:27:38 Или КодСимволаЧастичногоОтреза = Неопределено Или ЖурналОперацийДрайвера = Неопределено Тогда ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(НСтр("ru='Не настроены параметры устройства. |Для корректной работы устройства необходимо задать параметры его работы. |Сделать это можно при помощи формы ""Настройка параметров"" модели |подключаемого оборудования в форме ""Подключение и настройка оборудования"".'")); Результат = Ложь; КонецЕсли; Если Результат Тогда Если НЕ ОбъектДрайвера.FPInit(Параметры.Порт,Параметры.Скорость,Параметры.Таймаут,Параметры.Таймаут) тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; Результат = Ложь; Иначе ПараметрыПодключения.СерийныйНомерККМ = ОбъектДрайвера.GetSerialNumber; Если Результат И Параметры.ОтменятьЧекПриПодключении И ОбъектДрайвера.GetCheckOpened Тогда Результат = ОбъектДрайвера.FPResetOrder(); КонецЕсли; Если Результат И Не ОбъектДрайвера.GetSmenaOpened тогда // Если смена не открыта, проведем регламентные процедуры //Проверка времени ВремяСервера = МастерПроцедурыСервера.ТекущаяДатаНаСервере(); Если Результат И НЕ ОбъектДрайвера.CurrentDate=Формат(ВремяСервера,"ДФ=dd.MM.yyyy") тогда ОбъектДрайвера.CurrentDate=Формат(ВремяСервера,"ДФ=dd.MM.yyyy"); КонецЕсли; Если Результат И НЕ Лев(ОбъектДрайвера.CurrentTime,7)=Лев(Формат(ВремяСервера,"ДФ=hh:mm:ss"),7) тогда ОбъектДрайвера.CurrentTime=Формат(МастерПроцедурыСервера.ТекущаяДатаНаСервере(),"ДФ=hh:mm:ss"); КонецЕсли; Если Результат И ((НЕ ОбъектДрайвера.GetTaxQuantity=1) Или (НЕ ОбъектДрайвера.GetBaseTax_A=2000) Или (НЕ ОбъектДрайвера.GetTaxTypeExt=0) или (НЕ ОбъектДрайвера.GetUseMixedTax)) тогда Результат = ОбъектДрайвера.FPSetTaxRate(0, // Пароль программирования 1, // Количество программируемых групп, начиная с группы "А" 0, // Вложенный тип НДС ETaxType.ettWithNDS 2000, // Ставка НДС группы "А" в 0.01% 0, // Ставка НДС группы "Б" в 0.01% 0, // Ставка НДС группы "В" в 0.01% 0, // Ставка НДС группы "Г" в 0.01% 0, // Ставка НДС группы "Д" в 0.01% 0, // Сбор в пенсионный фонд группы "А" в 0.01% 0, // Сбор в пенсионный фонд группы "Б" в 0.01% 0, // Сбор в пенсионный фонд группы "В" в 0.01% 0, // Сбор в пенсионный фонд группы "Г" в 0.01% 0, // Сбор в пенсионный фонд группы "Д" в 0.01% ложь) // Использовать схему составного налога КонецЕсли; КонецЕсли; //Результат = Истина; Если Не Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; КонецЕсли; //мНДС = Новый Массив(); //мНДС.Добавить(20.00); //мНДС.Добавить(0.00); //мНДС.Добавить(0.00); //мНДС.Добавить(0.00); //МассивЗначений = Новый Массив; //МассивЗначений.Добавить(Параметры.Порт); //МассивЗначений.Добавить(Параметры.Скорость); //МассивЗначений.Добавить(Параметры.ПарольПользователя); //МассивЗначений.Добавить(Параметры.ПарольАдминистратора); //МассивЗначений.Добавить(Параметры.Таймаут); //МассивЗначений.Добавить(ПараметрыПодключения.СерийныйНомерККМ); //МассивЗначений.Добавить(мНДС[0]); //МассивЗначений.Добавить(мНДС[1]); //МассивЗначений.Добавить(мНДС[2]); //МассивЗначений.Добавить(мНДС[3]); //МассивЗначений.Добавить(Ложь); //МассивЗначений.Добавить(Параметры.ЖурналОперацийДрайвера); //МассивЗначений.Добавить(Параметры.НаименованиеОплаты1); //МассивЗначений.Добавить(Параметры.НаименованиеОплаты2); //Если НЕ ОбъектДрайвера.Подключить(МассивЗначений, ПараметрыПодключения.ИДУстройства) Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // Результат = Ложь; //Иначе // ПараметрыПодключения.СерийныйНомерККМ = МассивЗначений[5]; // Если Параметры.ОтменятьЧекПриПодключении Тогда // ОбъектДрайвера.ОтменитьЧек(ПараметрыПодключения.ИДУстройства); // КонецЕсли; // Результат = Истина; //КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 9:08:45 // Функция осуществляет отключение устройства. // // Параметры: // ОбъектДрайвера - <*> // - ОбъектДрайвера драйвера торгового оборудования. // // Возвращаемое значение: // <Булево> - Результат работы функции. // Функция ОтключитьУстройство(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Экспорт Результат = Ложь; ВыходныеПараметры = Новый Массив(); Результат = ОбъектДрайвера.FPClose(); Если НЕ Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //Если НЕ ОбъектДрайвера.Отключить(ПараметрыПодключения.ИДУстройства) Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); //Иначе // Результат = Истина; //КонецЕсли; Возврат Результат; КонецФункции // Функция получает, обрабатывает и перенаправляет на исполнение команду к драйверу // Функция ВыполнитьКоманду(Команда, ВходныеПараметры = Неопределено, ВыходныеПараметры = Неопределено, ОбъектДрайвера, Параметры, ПараметрыПодключения) Экспорт Результат = Истина; ВыходныеПараметры = Новый Массив(); // Открыть смену Если Команда = "OpenDay" Тогда Результат = ОткрытьСмену(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Печать чека ИначеЕсли Команда = "PrintReceipt" Тогда ТаблицаНоменклатуры = ВходныеПараметры[0]; ТаблицаОплат = ВходныеПараметры[1]; ОбщиеПараметры = ВходныеПараметры[2]; Результат = ПечатьЧека(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаНоменклатуры, ТаблицаОплат, ОбщиеПараметры, ВыходныеПараметры); // Печать слип чека ИначеЕсли Команда = "PrintText" Тогда СтрокаТекста = ВходныеПараметры[0]; Результат = ПечатьТекста(ОбъектДрайвера, Параметры, ПараметрыПодключения, СтрокаТекста, ВыходныеПараметры); // Печать чека внесения/выемки ИначеЕсли Команда = "Encash" Тогда ТипИнкассации = ВходныеПараметры[0]; Сумма = ВходныеПараметры[1]; Результат = Инкассация(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТипИнкассации, Сумма, ВыходныеПараметры); // Печать отчета без гашения ИначеЕсли Команда = "PrintXReport" Тогда Результат = НапечататьОтчетБезГашения(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Печать отчета с гашением ИначеЕсли Команда = "PrintZReport" Тогда Результат = НапечататьОтчетСГашением(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Тестирование устройства ИначеЕсли Команда = "CheckHealth" Тогда Результат = ТестУстройства(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Открытие денежного ящика ИначеЕсли Команда = "OpenCashDrawer" Тогда Результат = ОткрытьДенежныйЯщик(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Получение версии драйвера ИначеЕсли Команда = "ПолучитьВерсиюДрайвера" Тогда Результат = ПолучитьВерсиюДрайвера(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Указанная команда не поддерживается данным драйвером Иначе ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(НСтр("ru='Команда ""%Команда%"" не поддерживается данным драйвером.'")); ВыходныеПараметры[1] = СтрЗаменить(ВыходныеПараметры[1], "%Команда%", Команда); Результат = Ложь; КонецЕсли; Возврат Результат; КонецФункции ///////////////////////////////////// // Функции-исполнители команд ///////// СПЕЦИФИЧНЫЕ ПО ТИПУ ОБОРУДОВАНИЯ КОМАНДЫ //////////////// // Функция осуществляет открытие смены Функция ОткрытьСмену(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; Результат = ОбъектДрайвера.FPNullCheck(); Если НЕ Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; // Заполнение выходных параметров ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(ТекущаяДата()); Возврат Результат; КонецФункции // Осуществляет печать фискального чека Функция ПечатьЧека(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаНоменклатуры, ТаблицаОплат, ОбщиеПараметры, ВыходныеПараметры) Результат = Истина; ЧекНаВозврат = ОбщиеПараметры[0] = 1; // Открываем чек Результат = ОткрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ОбщиеПараметры[0] = 1, ОбщиеПараметры[1], ВыходныеПараметры); // Печатаем строки чека СуммаЧека = 0; Если Результат Тогда Для ИндексМассива = 0 По ТаблицаНоменклатуры.Количество() - 1 Цикл Наименование = ТаблицаНоменклатуры[ИндексМассива][0].Значение; Количество = ТаблицаНоменклатуры[ИндексМассива][5].Значение; Цена = ТаблицаНоменклатуры[ИндексМассива][4].Значение; ПроцентСкидки = ТаблицаНоменклатуры[ИндексМассива][8].Значение; Сумма = ТаблицаНоменклатуры[ИндексМассива][9].Значение; СуммаЧека = СуммаЧека + Сумма; НомерСекции = ТаблицаНоменклатуры[ИндексМассива][3].Значение; СтавкаНДС = ТаблицаНоменклатуры[ИндексМассива][12].Значение; Если (НЕ ЧекНаВозврат) И НЕ НапечататьФискальнуюСтроку(ОбъектДрайвера, Параметры, ПараметрыПодключения, Наименование, Количество, Цена, ПроцентСкидки, Сумма, НомерСекции, СтавкаНДС, ВыходныеПараметры) Тогда Прервать; ИначеЕсли (ЧекНаВозврат) И НЕ НапечататьФискальнуюСтрокуВозврат(ОбъектДрайвера, Параметры, ПараметрыПодключения, Наименование, Количество, Цена, ПроцентСкидки, Сумма, НомерСекции, СтавкаНДС, ВыходныеПараметры) Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; // Master 19.12.2011 7:49:24 необходимо проверить сумму ФР и базы // Закрываем чек Если Результат Тогда Результат = ЗакрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаОплат, ВыходныеПараметры); КонецЕсли; Возврат Результат; КонецФункции // Осуществляет печать слип-чека Функция ПечатьТекста(ОбъектДрайвера, Параметры, ПараметрыПодключения, СтрокаТекста, ВыходныеПараметры) Результат = Истина; // Открываем чек Результат = ОткрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, Ложь, Ложь, ВыходныеПараметры); // Печатаем строки чека Если Результат Тогда Для НомерСтроки = 1 По СтрЧислоСтрок(СтрокаТекста) Цикл ВыделеннаяСтрока = СтрПолучитьСтроку(СтрокаТекста, НомерСтроки); Если Найти(ВыделеннаяСтрока, Символ(Параметры.КодСимволаЧастичногоОтреза)) > 0 Тогда ТаблицаОплат = Новый Массив(); Результат = ЗакрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаОплат, ВыходныеПараметры); Результат = ОткрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, Ложь, Ложь, ВыходныеПараметры); Иначе Если НЕ НапечататьНефискальнуюСтроку(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыделеннаяСтрока, ВыходныеПараметры) Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; // Закрываем чек Если Результат Тогда ТаблицаОплат = Новый Массив(); Результат = ЗакрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаОплат, ВыходныеПараметры); КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 9:36:08 // Функция осуществляет открытие нового чека. // Функция ОткрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ЧекВозврата, ФискальныйЧек, ВыходныеПараметры) Результат = Истина; НомерСмены = 0; НомерЧека = 0; Результат = ОбъектДрайвера.GetSmenaOpened; Если не Результат тогда ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = "Смена закрыта, печать чека не возможна"; Возврат Результат; КонецЕсли; Результат = НЕ ОбъектДрайвера.GetCheckOpened; Если НЕ Результат тогда ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = "Последний чек не закрыт, закройте чек или перезапустите 1с"; Возврат Результат; КонецЕсли; ВыходныеПараметры.Добавить(ОбъектДрайвера.GetNumZReport+1); Если НЕ ЧекВозврата тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetSaleCheckNumber+1); Иначе ВыходныеПараметры.Добавить(ОбъектДрайвера.GetPayCheckNumber+1); КонецЕсли; ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(ТекущаяДата()); // Открываем чек //Результат = ОбъектДрайвера.ОткрытьЧек(ПараметрыПодключения.ИДУстройства, ФискальныйЧек, ЧекВозврата, // Истина, НомерЧека, НомерСмены); //Если НЕ Результат Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); //Иначе // // Заполнение выходных параметров // ВыходныеПараметры.Добавить(НомерСмены); // ВыходныеПараметры.Добавить(НомерЧека); // ВыходныеПараметры.Добавить(0); // ВыходныеПараметры.Добавить(ТекущаяДата()); //КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 14:03:27 // Функция осуществляет печать фискальной строки. // Функция НапечататьФискальнуюСтроку(ОбъектДрайвера, Параметры, ПараметрыПодключения, Наименование, Количество, Цена, ПроцентСкидки, Сумма, НомерСекции, СтавкаНДС, ВыходныеПараметры) Результат = Истина; ТКоличество1 = Формат(Количество*1000,"ЧЦ=12; ЧДЦ=0; ЧГ=0"); ТКоличество2 = Формат(Окр(Количество,0)*1000,"ЧЦ=12; ЧДЦ=0; ЧГ=0"); IsOneQuant = Истина; Если ТКоличество1=ТКоличество2 тогда ТКоличество1 = Количество; //IsOneQuant = Истина; Иначе IsOneQuant = Ложь; ТКоличество1 = Число(ТКоличество1); КонецЕсли; Результат = ОбъектДрайвера.FPSaleEx (ТКоличество1, // количество 3, // количество знаков дробной части кол- ва IsOneQuant, Формат(Цена*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"), // цена в копейках 0, // налоговая группа « А» ложь, // не брать описание товара из ЭККР Лев(Наименование,50), // название товара МастерПроцедурыСервера.Хэш(Лев(Наименование,50),,,214783648)); // Код товара Если ПроцентСкидки > 0 тогда ОбъектДрайвера.FPDiscount(2,Формат(ПроцентСкидки*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"),""); ИначеЕсли ПроцентСкидки < 0 тогда ОбъектДрайвера.FPDiscount(3,Формат(ПроцентСкидки*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"),""); КонецЕсли; Если НЕ Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //Результат = ОбъектДрайвера.НапечататьФискСтроку(ПараметрыПодключения.ИДУстройства, Наименование, Количество, Цена, // Сумма, НомерСекции, СтавкаНДС); //Если НЕ Результат Тогда // ВыходныеПараметры.Очистить(); // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); //КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 14:03:27 // Функция осуществляет печать фискальной строки. // Функция НапечататьФискальнуюСтрокуВозврат(ОбъектДрайвера, Параметры, ПараметрыПодключения, Наименование, Количество, Цена, ПроцентСкидки, Сумма, НомерСекции, СтавкаНДС, ВыходныеПараметры) Результат = Истина; ТКоличество1 = Формат(Количество*1000,"ЧЦ=12; ЧДЦ=0; ЧГ=0"); ТКоличество2 = Формат(Окр(Количество,0)*1000,"ЧЦ=12; ЧДЦ=0; ЧГ=0"); IsOneQuant = Истина; Если ТКоличество1=ТКоличество2 тогда ТКоличество1 = Количество; //IsOneQuant = Истина; Иначе IsOneQuant = Ложь; ТКоличество1 = Число(ТКоличество1); КонецЕсли; Результат = ОбъектДрайвера.FPPayMoneyEx(ТКоличество1, // количество 3, // количество знаков дробной части кол- ва IsOneQuant, Формат(Цена*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"), // цена в копейках 0, // налоговая группа « А» ложь, // не брать описание товара из ЭККР Лев(Наименование,50), // название товара МастерПроцедурыСервера.Хэш(Лев(Наименование,50),,,214783648)); // Код товара Если ПроцентСкидки > 0 тогда ОбъектДрайвера.FPDiscount(2,Формат(ПроцентСкидки*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"),""); ИначеЕсли ПроцентСкидки < 0 тогда ОбъектДрайвера.FPDiscount(3,Формат(ПроцентСкидки*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"),""); КонецЕсли; Если НЕ Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //Результат = ОбъектДрайвера.НапечататьФискСтроку(ПараметрыПодключения.ИДУстройства, Наименование, Количество, Цена, // Сумма, НомерСекции, СтавкаНДС); //Если НЕ Результат Тогда // ВыходныеПараметры.Очистить(); // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); //КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 14:03:16 // Функция осуществляет печать нефискальной строки. // Функция НапечататьНефискальнуюСтроку(ОбъектДрайвера, Параметры, ПараметрыПодключения, СтрокаТекста, ВыходныеПараметры) Результат = Истина; Результат = ОбъектДрайвера.НапечататьНефискСтроку(ПараметрыПодключения.ИДУстройства, СтрокаТекста); Если НЕ Результат Тогда ВыходныеПараметры.Очистить(); ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(""); ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 13:57:52 // Функция осуществляет закрытие ранее открытого чека. // Функция ЗакрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаОплат, ВыходныеПараметры) Результат = Истина; СуммаНаличнойОплаты = 0; СуммаБезналичнойОплаты1 = 0; СуммаБезналичнойОплаты2 = 0; Результат = ОбъектДрайвера.GetCheckOpened; Если НЕ Результат тогда ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = "Чек не открыт, закрытие не возможно"; Возврат Результат; КонецЕсли; Для ИндексОплаты = 0 По ТаблицаОплат.Количество() - 1 Цикл Если ТаблицаОплат[ИндексОплаты][0].Значение = 0 Тогда СуммаНаличнойОплаты = СуммаНаличнойОплаты + ТаблицаОплат[ИндексОплаты][1].Значение; ИначеЕсли ТаблицаОплат[ИндексОплаты][0].Значение = 1 Тогда СуммаБезналичнойОплаты1 = СуммаБезналичнойОплаты1 + ТаблицаОплат[ИндексОплаты][1].Значение; Иначе СуммаБезналичнойОплаты2 = СуммаБезналичнойОплаты2 + ТаблицаОплат[ИндексОплаты][1].Значение; КонецЕсли; КонецЦикла; ЗакрытьАвто = Ложь; Если НЕ СуммаНаличнойОплаты=0 тогда Если СуммаБезналичнойОплаты1=0 и СуммаБезналичнойОплаты2=0 тогда ЗакрытьАвто = Истина; КонецЕсли; Результат = ОбъектДрайвера.FPPayment (3, // форма оплат – наличными Формат((СуммаНаличнойОплаты*100),"ЧЦ=12; ЧДЦ=0; ЧГ=0"), // сумма оплаты в копейках ЗакрытьАвто, // чек не будет закрыт автоматически Истина , // чек закроется как фискальный ""); // комментарий к этой оплате КонецЕсли; Если Результат И (НЕ СуммаБезналичнойОплаты1=0) тогда Если СуммаБезналичнойОплаты2=0 тогда ЗакрытьАвто = Истина; КонецЕсли; Результат = ОбъектДрайвера.FPPayment (0, // форма оплат – наличными Формат(СуммаБезналичнойОплаты1*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"), // сумма оплаты в копейках ЗакрытьАвто, // чек не будет закрыт автоматически Истина , // чек закроется как фискальный "Карта №1"); // комментарий к этой оплате КонецЕсли; Если Результат И (НЕ СуммаБезналичнойОплаты2=0) тогда Результат = ОбъектДрайвера.FPPayment (0, // форма оплат – наличными Формат(СуммаБезналичнойОплаты2*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0"), // сумма оплаты в копейках Истина, // чек не будет закрыт автоматически Истина , // чек закроется как фискальный "Карта №2"); // комментарий к этой оплате КонецЕсли; Если НЕ Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); КонецЕсли; //Для ИндексОплаты = 0 По ТаблицаОплат.Количество() - 1 Цикл // Если ТаблицаОплат[ИндексОплаты][0].Значение = 0 Тогда // СуммаНаличнойОплаты = СуммаНаличнойОплаты + ТаблицаОплат[ИндексОплаты][1].Значение; // ИначеЕсли ТаблицаОплат[ИндексОплаты][0].Значение = 1 Тогда // СуммаБезналичнойОплаты1 = СуммаБезналичнойОплаты1 + ТаблицаОплат[ИндексОплаты][1].Значение; // Иначе // СуммаБезналичнойОплаты2 = СуммаБезналичнойОплаты2 + ТаблицаОплат[ИндексОплаты][1].Значение; // КонецЕсли; //КонецЦикла; //Результат = ОбъектДрайвера.ЗакрытьЧек(ПараметрыПодключения.ИДУстройства, // СуммаНаличнойОплаты, // СуммаБезналичнойОплаты1, // СуммаБезналичнойОплаты2); //Если НЕ Результат Тогда // ВыходныеПараметры.Очистить(); // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); //КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 13:57:41 // Функция осуществляет отмену ранее открытого чека. // Функция ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; Результат = ОбъектДрайвера.GetCheckOpened; Если Результат тогда // Если Чек открыт только тогда аннулируем Результат = ОбъектДрайвера.FPResetOrder(); КонецЕсли; Если НЕ Результат тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //ОбъектДрайвера.ОтменитьЧек(ПараметрыПодключения.ИДУстройства); Возврат Результат; КонецФункции // Master 16.12.2011 9:51:52 // Функция осуществляет внесение или выемку суммы на ФР. // Функция Инкассация(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТипИнкассации, Сумма, ВыходныеПараметры) Результат = Истина; Если ТипИнкассации=1 тогда Результат = ОбъектДрайвера.FPInToCash(Формат(Сумма*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0")); Иначе Результат = ОбъектДрайвера.FPOutOfCash(Формат(Сумма*100,"ЧЦ=12; ЧДЦ=0; ЧГ=0")); КонецЕсли; Если НЕ Результат Тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = ОбъектДрайвера.GetTextErrorMessage; Иначе // Заполнение выходных параметров ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(0); ВыходныеПараметры.Добавить(ТекущаяДата()); КонецЕсли; // Результат = ОбъектДрайвера.НапечататьЧекВнесенияВыемки(ПараметрыПодключения.ИДУстройства, // ?(ТипИнкассации = 1, Сумма, -Сумма)); // Если НЕ Результат Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // КодОшибки = ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); // Иначе // // Заполнение выходных параметров // ВыходныеПараметры.Добавить(0); // ВыходныеПараметры.Добавить(0); // ВыходныеПараметры.Добавить(0); // ВыходныеПараметры.Добавить(ТекущаяДата()); // КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 9:08:28 // Функция осуществляет снятие отчёта без гашения. // Функция НапечататьОтчетБезГашения(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; Результат = ОбъектДрайвера.FPDayReport(Параметры.ПарольАдминистратора); Если НЕ Результат Тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1]=ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //Результат = ОбъектДрайвера.НапечататьОтчетБезГашения(ПараметрыПодключения.ИДУстройства); //Если НЕ Результат Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); //Иначе // //КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 9:07:11 // Функция осуществляет снятие отчёта с гашением. // Функция НапечататьОтчетСГашением(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; ТОстатокДенегВФР = ОбъектДрайвера.GetMoneyInBox; ОстатокДенегВФР = ?(ПустаяСтрока(ТОстатокДенегВФР),0,Число(ТОстатокДенегВФР)); Если НЕ ОстатокДенегВФР=0 тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1] = "Остаток суммы наличных в денежном ящике: "+Формат(ОстатокДенегВФР/100,"ЧЦ=12; ЧДЦ=2; ЧРГ=; ЧГ=3,0"); Возврат Ложь; КонецЕсли; Результат = ОбъектДрайвера.FPDayClrReport(Параметры.ПарольАдминистратора); Если НЕ Результат Тогда ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1]=ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //Результат = ОбъектДрайвера.НапечататьОтчетСГашением(ПараметрыПодключения.ИДУстройства); //Если НЕ Результат Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); // ОтменитьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры); //Иначе // //КонецЕсли; Возврат Результат; КонецФункции // Master 16.12.2011 9:06:12 // Функция осуществляет открытие денежного ящика // Функция ОткрытьДенежныйЯщик(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; Результат = ОбъектДрайвера.FPOpenBox(); Если НЕ Результат Тогда ВыходныеПараметры.Добавить(ОбъектДрайвера.GetByteResult); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1]=ОбъектДрайвера.GetTextErrorMessage; КонецЕсли; //Попытка // Результат = ОбъектДрайвера.ОткрытьДенежныйЯщик(ПараметрыПодключения.ИДУстройства, 0); // номер ящика по умолчанию 0 //Исключение // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(НСтр("ru='Команда ""Открыть денежный ящик"" не поддерживается данным драйвером.'")); // Возврат Результат; //КонецПопытки; // //Если НЕ Результат Тогда // ВыходныеПараметры.Добавить(999); // ВыходныеПараметры.Добавить(""); // ОбъектДрайвера.ПолучитьОшибку(ВыходныеПараметры[1]); //КонецЕсли; Возврат Результат; КонецФункции //////////// ДОПОЛНИТЕЛЬНЫЕ КОМАНДЫ //////////////////// // Master 16.12.2011 9:06:22 // Функция осуществляет тестирование устройства // Функция ТестУстройства(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; РезультатТеста = ""; СерийныйНомерККМ = "0"; //мНДС = Новый Массив(); //мНДС.Добавить(20.00); //мНДС.Добавить(0.00); //мНДС.Добавить(0.00); //мНДС.Добавить(0.00); //МассивЗначений = Новый Массив; //МассивЗначений.Добавить(Параметры.Порт); //МассивЗначений.Добавить(Параметры.Скорость); //МассивЗначений.Добавить(Параметры.ПарольПользователя); //МассивЗначений.Добавить(Параметры.ПарольАдминистратора); //МассивЗначений.Добавить(Параметры.Таймаут); //МассивЗначений.Добавить(СерийныйНомерККМ); //МассивЗначений.Добавить(мНДС[0]); //МассивЗначений.Добавить(мНДС[1]); //МассивЗначений.Добавить(мНДС[2]); //МассивЗначений.Добавить(мНДС[3]); //МассивЗначений.Добавить(Ложь); //МассивЗначений.Добавить(Параметры.ЖурналОперацийДрайвера); //МассивЗначений.Добавить(Параметры.НаименованиеОплаты1); //МассивЗначений.Добавить(Параметры.НаименованиеОплаты2); //Результат = ОбъектДрайвера.ТестУстройства(МассивЗначений, РезультатТеста); // Master 15.12.2011 14:03:11 // { Master 15.12.2011 14:03:16 Если НЕ ОбъектДрайвера.FPInit(Параметры.Порт,Параметры.Скорость,Параметры.Таймаут,Параметры.Таймаут) тогда ВыходныеПараметры.Добавить(999); ВыходныеПараметры.Добавить(""); ВыходныеПараметры[1]=ОбъектДрайвера.GetTextErrorMessage; попытка ОбъектДрайвера.FPClose(); // попробуем закрыть сессию Исключение КонецПопытки; Иначе Результат = ОбъектДрайвера.FPLineFeed(); ОбъектДрайвера.FPSendCustomer(True,"Work with 1C"); ОбъектДрайвера.FPPrintVersion(); ОбъектДрайвера.FPClose(); КонецЕсли; // } ВыходныеПараметры.Добавить(?(Результат, 0, 999)); ВыходныеПараметры.Добавить(РезультатТеста); Возврат Результат; КонецФункции // Master 16.12.2011 9:06:51 // Функция возвращает версию установленного драйвера // Функция ПолучитьВерсиюДрайвера(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Результат = Истина; ВыходныеПараметры.Добавить(НСтр("ru='Установлен'")); ВыходныеПараметры.Добавить(НСтр("ru='Не определена'")); // { Master 15.12.2011 13:42:25 //Так как в драйвере ИКС нет значение драйвера, возвращем неопределена // } Попытка Если ОбъектДрайвера.FPInit(Параметры.Порт,Параметры.Скорость,Параметры.Таймаут,Параметры.Таймаут) тогда ВыходныеПараметры[1] = ОбъектДрайвера.GetHardwareVersion; ОбъектДрайвера.FPClose(); КонецЕсли; // ВыходныеПараметры[1] = ОбъектДрайвера.ПолучитьНомерВерсии(); Исключение КонецПопытки; Возврат Результат; КонецФункции
Wednesday, December 21, 2011
Доработка по работе с ФР ИКС протоколом ЕП02 в Управление торговлей, редакция 11.0 (11.0.7.13)
1. Добавляем новое перечисление в ОбработчикиДрайверовПодключаемогоОборудования ОбработчикИКСФискальныеРегистраторы
2. Далее добавляем новый модуль в "Общие модули" с названием "ПодключаемоеОборудованиеИКСМФискальныеРегистраторы". В принцыпе, я взял модуль Штрих-м и переписал его под ИКС
Исправление YearOffset в ms sql базах 1с
Имеем проблему разных дат в базах 1с.
То есть если при установке базы данных установили смещение дат 2000, то в скуле все записи дат будут с 4000 года, что вызывает небольшой дискомфорт при обмене данными средствами sql.
Для исправления этого недоразумения был найден этот скриптик, в принципе идея в голове летала, вот только время на реализацию все не было.
Так что спасибо
Волшебному форуму, а именно пользователю Господин ПЖ
use rl_distrib;
Declare TablesAndFields cursor for
SELECT objects.name as Tablename, columns.name as columnname
FROM
dbo.sysobjects as objects
left join dbo.syscolumns as columns
on objects.id = columns.id
where objects.xtype = 'U'
and columns.xtype = 61
open TablesAndFields
Declare @TableName as varchar(100)
Declare @ColumnName as varchar(100)
FETCH NEXT FROM TablesAndFields
into @TableName, @ColumnName
WHILE @@FETCH_STATUS = 0
BEGIN
Exec ('update ' + @TableName + '
set ' + @ColumnName + ' = dateAdd(year,-2000,'+@ColumnName+')
where ' + @ColumnName + ' > ''3000-12-31T23:59:59''')
-- This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM TablesAndFields
into @TableName, @ColumnName
END
close TablesAndFields
deallocate TablesAndFields
update dbo._YearOffset set Offset=0
Wednesday, December 14, 2011
Рассылка прайса фоновое задание в 1с
Дальнейшее продвижение формирование прайса, нарвался на несолько проблем:
1. На 2008R2x64 сервере под стандартным пользователем 1с уперто не хотела дружить с Excelом,
" Ошибка при вызове конструктора (COMОбъект)", так что пришлось запустить под доменной учетной записью сервер.
2. Первая проблема решилась, но появилась вторая
"Ошибка при вызове метода контекста (SaveAs): Произошла исключительная ситуация (Microsoft Excel): SaveAs method of Workbook class failed", покопавшись в нете в общей суме день нашел решение в создании 1 папки C:\Windows\SysWOW64\config\systemprofile\Desktop После этого рассылка прайса заработала на отлично.
ссылка на оригинал: http://social.msdn.microsoft.com/Forums/en-US/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91
1. На 2008R2x64 сервере под стандартным пользователем 1с уперто не хотела дружить с Excelом,
" Ошибка при вызове конструктора (COMОбъект)", так что пришлось запустить под доменной учетной записью сервер.
2. Первая проблема решилась, но появилась вторая
"Ошибка при вызове метода контекста (SaveAs): Произошла исключительная ситуация (Microsoft Excel): SaveAs method of Workbook class failed", покопавшись в нете в общей суме день нашел решение в создании 1 папки C:\Windows\SysWOW64\config\systemprofile\Desktop После этого рассылка прайса заработала на отлично.
ссылка на оригинал: http://social.msdn.microsoft.com/Forums/en-US/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91
Monday, November 28, 2011
Выгрузка прайс-лист из 1с8 в excel
// Обработка формирование прайс лист в excel
// Данная обработка формирует прайс и группирует данные в книге Excel, так как в 1С работают группировки в 1С
Перем Ексель,Лист,НомерСтроки;
Перем НомерКолонкиНаименования, НомерКолонкиКода, НомерКолонкиЦены, НомерКолонкиГарантия, НомерКолонкиЗаказ;
Перем МаксУровней,ДатаФормированияПрайса;
Функция rgb(r,g,b)
Возврат r+g*256+b*65536;
КонецФункции
Процедура ВыгрузитьСтроки(Корень,Уровень)
НачСтрока=НомерСтроки;
Строки=Корень.Строки.НайтиСтроки(Новый Структура("ЭтоГруппа",Истина),Ложь);
Для каждого Стр из Строки Цикл
Range = Лист.Range(Лист.Cells(НомерСтроки, НомерКолонкиКода), Лист.Cells(НомерСтроки, 6));
Range.Merge();
Range.Value = Стр.Наименование;
Range.Font.Name = "Baskerville Old Face";
Range.Font.Size = 16-Стр.Уровень();
Range.IndentLevel = Стр.Уровень();
Range.Font.Bold = 1;
НомерСтроки=НомерСтроки+1;
ВыгрузитьСтроки(Стр,Стр.Уровень());
КонецЦикла;
Строки=Корень.Строки.НайтиСтроки(Новый Структура("ЭтоГруппа",Ложь),Ложь);
Для каждого Стр из Строки Цикл
//Лист.Cells(НомерСтроки,1).Value=Стр.Наименование;
//Лист.Cells(НомерСтроки,2).Value=Стр.Цена;
Лист.Cells(НомерСтроки, НомерКолонкиКода).Value = Стр.Код;
Лист.Cells(НомерСтроки, НомерКолонкиНаименования).Value = Стр.НаименованиеПолное;
Лист.Cells(НомерСтроки, НомерКолонкиНаименования).IndentLevel = Стр.Уровень();
Если стрДлина(Стр.СсылкаUrl)>0 тогда
Лист.Hyperlinks.Add(Лист.Cells(НомерСтроки, НомерКолонкиНаименования),Стр.СсылкаUrl,Стр.НаименованиеПолное);
КонецЕсли;
Лист.Cells(НомерСтроки, НомерКолонкиЦены).NumberFormat ="# ##0,00";
Лист.Cells(НомерСтроки, НомерКолонкиЦены).Value = Стр.Цена;
Лист.Cells(НомерСтроки, НомерКолонкиГарантия).NumberFormat = "0";
Лист.Cells(НомерСтроки, НомерКолонкиГарантия).Value = Стр.Гарантия;
Range = Лист.Range(Лист.Cells(НомерСтроки, 2), Лист.Cells(НомерСтроки, 6));
Range.Font.Name = "Arial";
Range.Font.Size = 8;
Если Стр.Изменение тогда
Range.Font.Bold = 1;
КонецЕсли;
Если НомерСтроки%2 тогда
Range. Interior.Color = rgb(227,237,249);
КонецЕсли;
Лист.Cells(НомерСтроки, НомерКолонкиЗаказ).NumberFormat = "0";
Лист.Cells(НомерСтроки, НомерКолонкиЗаказ).Interior.Color = rgb(218,238,243);
НомерСтроки=НомерСтроки+1;
КонецЦикла;
Если (Уровень>=0) и (НомерСтроки>НачСтрока) Тогда
Лист.Range(Лист.Cells(НачСтрока,1),Лист.Cells(НомерСтроки-1,2)).Rows.Group();
КонецЕсли;
МаксУровней = Макс(Уровень,МаксУровней);
КонецПроцедуры
Функция ОграничениеЗапросаПоНоменклатуре(ВнЗапрос)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураДляПрайсаСрезПоследних.Номенклатура КАК Номенклатура,
| НоменклатураДляПрайсаСрезПоследних.Отбор КАК Отбор
|ИЗ
| РегистрСведений.НоменклатураДляПрайса.СрезПоследних(&ДатаФормированияПрайса, Активен) КАК НоменклатураДляПрайсаСрезПоследних";
Запрос.УстановитьПараметр("ДатаФормированияПрайса", ДатаФормированияПрайса);
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
СтрокаОтбора = "И ( ";
Первый = Истина;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
//ПредопределенноеЗначение(Перечисления.ОтборВЗапросах.Равно)
Ун = СтрЗаменить(ВыборкаДетальныеЗаписи.Номенклатура.УникальныйИдентификатор(),"-","");
СтрокаПараметра = "Отбор"+Ун;//.Наименование;// + ВыборкаДетальныеЗаписи.Отбор; // Пока не важно так как 1 значение в регистре
ВнЗапрос.УстановитьПараметр(СтрокаПараметра,ВыборкаДетальныеЗаписи.Номенклатура);
Если Первый тогда
БулеваяОперация = "";
Первый = Ложь;
Иначе
БулеваяОперация = " ИЛИ ";
КонецЕсли;
СтрокаОтбора = СтрокаОтбора +БулеваяОперация+ " (Номенклатура.Ссылка " + ВыборкаДетальныеЗаписи.Отбор + " (&" + СтрокаПараметра + "))";
КонецЦикла;
СтрокаОтбора = СтрокаОтбора + ")";
ВнЗапрос.Текст = СтрЗАменить(ВнЗапрос.Текст,"//Добавление отбора",СтрокаОтбора);
КонецФункции
Процедура КнопкаВыполнитьНажатие(Кнопка)
Попытка
Ексель = Новый COMОбъект("Excel.Application");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
конецПопытки;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ПОМЕСТИТЬ СправочникНоменклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| (НЕ Номенклатура.ЭтоГруппа)
| И ИСТИНА //Добавление отбора
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура,
| ТоварыНаСкладахОстатки.КоличествоОстаток,
| ЦеныНоменклатурыСрезПоследних.Цена,
| ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры
|ПОМЕСТИТЬ Начало
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &ТекДата,
| Склад В (&Склад)
| И Номенклатура В
| (ВЫБРАТЬ
| СправочникНоменклатура.Ссылка
| ИЗ
| СправочникНоменклатура КАК СправочникНоменклатура)) КАК ТоварыНаСкладахОстатки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
| &ТекДата,
| ТипЦен = &ТипЦен
| И Валюта = &Валюта) КАК ЦеныНоменклатурыСрезПоследних
| ПО ТоварыНаСкладахОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
| И ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры = ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Начало.Номенклатура,
| Начало.КоличествоОстаток,
| Начало.Цена,
| Начало.ХарактеристикаНоменклатуры,
| ВЫБОР
| КОГДА ЦеныНоменклатурыСрезПоследних.Цена = Начало.Цена
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК Изменение
|ПОМЕСТИТЬ ТблИзмЦен
|ИЗ
| Начало КАК Начало
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
| ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, -1),
| ТипЦен = &ТипЦен
| И Валюта = &Валюта) КАК ЦеныНоменклатурыСрезПоследних
| ПО Начало.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
| И Начало.ХарактеристикаНоменклатуры = ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка
|ПОМЕСТИТЬ ТблПриходов
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, -1) И &ТекДата
| И ПоступлениеТоваровУслуг.Проведен
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТблИзмЦен.Номенклатура,
| ТблИзмЦен.КоличествоОстаток,
| ТблИзмЦен.Цена,
| ТблИзмЦен.ХарактеристикаНоменклатуры,
| ВЫБОР
| КОГДА СУММА(ЕСТЬNULL(ПоступлениеТоваровУслугТовары.Количество, 0)) > 0
| ТОГДА ИСТИНА
| ИНАЧЕ ТблИзмЦен.Изменение
| КОНЕЦ КАК Изменение
|ПОМЕСТИТЬ ИтоговаяТбл
|ИЗ
| ТблИзмЦен КАК ТблИзмЦен
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
| ПО ТблИзмЦен.Номенклатура = ПоступлениеТоваровУслугТовары.Номенклатура
| И ТблИзмЦен.ХарактеристикаНоменклатуры = ПоступлениеТоваровУслугТовары.ХарактеристикаНоменклатуры
| И (ПоступлениеТоваровУслугТовары.Ссылка В
| (ВЫБРАТЬ
| ТблПриходов.Ссылка
| ИЗ
| ТблПриходов КАК ТблПриходов))
| И (ПоступлениеТоваровУслугТовары.Склад В (&Склад))
|
|СГРУППИРОВАТЬ ПО
| ТблИзмЦен.Номенклатура,
| ТблИзмЦен.КоличествоОстаток,
| ТблИзмЦен.Цена,
| ТблИзмЦен.ХарактеристикаНоменклатуры,
| ТблИзмЦен.Изменение
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ИтоговаяТбл.Номенклатура КАК Номенклатура,
| ИтоговаяТбл.КоличествоОстаток,
| ИтоговаяТбл.Цена,
| ИтоговаяТбл.ХарактеристикаНоменклатуры,
| ИтоговаяТбл.Изменение,
| ИтоговаяТбл.Номенклатура.СсылкаUrl КАК СсылкаUrl,
| ЗначенияСвойствОбъектов.Значение КАК Гарантия,
| ИтоговаяТбл.Номенклатура.Код КАК Код,
| ИтоговаяТбл.Номенклатура.НаименованиеПолное КАК НаименованиеПолное,
| ИтоговаяТбл.Номенклатура.Наименование КАК Наименование,
| ИтоговаяТбл.Номенклатура.ЭтоГруппа КАК ЭтоГруппа
|ИЗ
| ИтоговаяТбл КАК ИтоговаяТбл
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
| ПО ИтоговаяТбл.Номенклатура = ЗначенияСвойствОбъектов.Объект
| И (ЗначенияСвойствОбъектов.Свойство = ЗНАЧЕНИЕ(ПланВидовХарактеристик.СвойстваОбъектов.Гарантия))
|ГДЕ
| ИСТИНА
|ИТОГИ ПО
| Номенклатура ТОЛЬКО ИЕРАРХИЯ
|АВТОУПОРЯДОЧИВАНИЕ";
ОграничениеЗапросаПоНоменклатуре(Запрос);
Запрос.УстановитьПараметр("ТекДата",ДатаФормированияПрайса);
Запрос.УстановитьПараметр("ТипЦен",Справочники.ТипыЦенНоменклатуры.НайтиПоКоду("000000020"));
Запрос.УстановитьПараметр("Валюта",Константы.ВалютаУправленческогоУчета.Получить());
СписокСкладов = Новый СписокЗначений;
СписокСкладов.Добавить(Справочники.Склады.НайтиПоКоду("002200001")); //Центральный склад
СписокСкладов.Добавить(Справочники.Склады.НайтиПоКоду("002500019")); //Футляры Центральный склад
Запрос.УстановитьПараметр("Склад",СписокСкладов);
Результат = Запрос.Выполнить();
Ексель.DisplayAlerts=Ложь;
Ексель.Visible = ложь;
Книга = Ексель.Workbooks.Add();
Лист = Книга.WorkSheets(1);
Лист.Select();
Ексель.Application.ActiveWindow.SplitRow = 4;
Ексель.Application.ActiveWindow.FreezePanes = 1;
Коеф = 27;
кнопка1 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1", , , , , , , 3, 3, 80, 20);
кнопка1.Name = "Свернуть";
кнопка1.TextFrame.Characters().Text = "Свернуть";
кнопка2 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1", , , , , , , 100, 3, 80, 20);
кнопка1.Name = "ПоказатьВсе";
кнопка1.Name = "КнопкаСвернуть";
кнопка1.Caption = "Свернуть";
кнопка1 = Книга.WorkSheets(1).Buttons.Add(100, 3, 80, 20);
кнопка1.Name = "КнопкаСвернуть";
кнопка1.Caption = "Свернуть";
кнопка1 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1",,,,,,,3, 3, 80, 25);
кнопка1.Name = "КнопкаПоказатьВсе";
Книга.WorkSheets(1).oleobjects(1).Object.Caption = "Показать все";
ст = "Sub Main()
|MsgBox(""Hello, World!"") ' Display message on computer screen.
|End Sub";
Ексель.VBE.ActiveVBProject.VBComponents.Add (1);
Ексель.VBE.ActiveVBProject.VBComponents.Item(1).CodeModule.InsertLines (1, ст);
Ексель.Application.Save();
кнопка2 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1",,,,,,,100, 3, 80, 25);
кнопка2.Name = "КнопкаСвернуть";
Книга.WorkSheets(1).oleobjects(2).Object.Caption = "Свернуть все" ;
кнопка2 = Книга.WorkSheets(1).Buttons.Add(3, 3, 80, 20);
кнопка2.Name = "КнопкаПоказатьВсе";
кнопка2.Caption = "Показать все";
Лист.Outline.SummaryRow = 0;
// { Master 25.11.2011 17:52:33 Прайс-лист
Range = Лист.Range(Лист.Cells(1, 2), Лист.Cells(1, 6));
Range.Merge();
Range.Value = "Прайс-лист";
Range.Font.Name = "Courier New";
Range.Font.Size = 22;
Range.HorizontalAlignment =3;
Range.VerticalAlignment =2;
// }
Лист.Cells(2, 2).Value = "Цены указаны на "+ Формат(ДатаФормированияПрайса,"ДФ=dd.MM.yyyy");
Лист.Cells(2, 2).Name = "Arial";
Лист.Cells(2, 2).Font.Size = 8;
НомерСтроки = 5;
НомерКолонкиНаименования = 3;
НомерКолонкиКода = 2;
НомерКолонкиЦены = 4;
НомерКолонкиГарантия = 5;
НомерКолонкиЗаказ = 6;
// { Master 25.11.2011 17:52:33 Название номенклатура
Range = Лист.Range(Лист.Cells(3, НомерКолонкиКода), Лист.Cells(4, НомерКолонкиКода));
Range.Merge();
Range.Value = "Код";
// }
// { Master 25.11.2011 17:52:33 Название номенклатура
Range = Лист.Range(Лист.Cells(3, НомерКолонкиНаименования), Лист.Cells(4, НомерКолонкиНаименования));
Range.Merge();
Range.Value = "Номенклатура";
// }
// { Master 25.11.2011 17:52:56
Range = Лист.Range(Лист.Cells(3, НомерКолонкиЦены), Лист.Cells(4, НомерКолонкиЦены));
Range.Merge();
Range.Value = "Цена";
// }
// { Master 25.11.2011 17:52:56
Range = Лист.Range(Лист.Cells(3, НомерКолонкиГарантия), Лист.Cells(4, НомерКолонкиГарантия));
Range.Merge();
Range.Value = "Гарантия (мес.)";
Range.WrapText = Истина;
// }
// { Master 25.11.2011 17:52:56
Range = Лист.Range(Лист.Cells(3, НомерКолонкиЗаказ), Лист.Cells(4, НомерКолонкиЗаказ));
Range.Merge();
Range.Value = "Заказ";
// }
Range = Лист.Range(Лист.Cells(3, 2), Лист.Cells(4, 6));
Range.Font.Name = "Arial Narrow";
Range.Font.Size = 12;
Range.HorizontalAlignment =3;
Range.VerticalAlignment =2;
Range.Borders(1).Weight = 2;
Range.Borders(2).Weight = 2;
Range.Borders(3).Weight = 2;
Range.Interior.Color = rgb(54,96,146);
Range.Font.Color = rgb(255,255,255);
Лист.Columns(1).ColumnWidth = 3;
Лист.Columns(НомерКолонкиКода).ColumnWidth = 11;
Лист.Columns(НомерКолонкиНаименования).ColumnWidth = 80;
Лист.Columns(НомерКолонкиЦены).ColumnWidth = 15;
Лист.Columns(НомерКолонкиГарантия).ColumnWidth = 7.86;
Лист.Columns(НомерКолонкиЗаказ).ColumnWidth = 12;
Дерево=Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ВыгрузитьСтроки(Дерево,-1);
Range = Лист.Range(Лист.Cells(5, 2), Лист.Cells(НомерСтроки-1, 6));
Range.Borders(1).Weight = 2;
Range.Borders(2).Weight = 2;
Range.Borders(3).Weight = 2;
Range.Borders(4).Weight = 2;
//область = Лист.Range(Формат(5,"ЧГ=0")+":"+Формат(НомерСтроки,"ЧГ=0"));
//область.Rows.Group();
//Лист.Outline.ShowLevels(2);
//Лист.Outline.ShowLevels(1);
Книга.SaveAs("c:\work\Price_"+Формат(ДатаФормированияПрайса,"ДФ=yyyy-MM-dd")+".xls",56);
Книга.Close();
Ексель.Quit();
КонецПроцедуры
МаксУровней = -1;
//ДатаФормированияПрайса = Дата(2011,11,1);
ДатаФормированияПрайса = ТекущаяДата();
// Данная обработка формирует прайс и группирует данные в книге Excel, так как в 1С работают группировки в 1С
Перем Ексель,Лист,НомерСтроки;
Перем НомерКолонкиНаименования, НомерКолонкиКода, НомерКолонкиЦены, НомерКолонкиГарантия, НомерКолонкиЗаказ;
Перем МаксУровней,ДатаФормированияПрайса;
Функция rgb(r,g,b)
Возврат r+g*256+b*65536;
КонецФункции
Процедура ВыгрузитьСтроки(Корень,Уровень)
НачСтрока=НомерСтроки;
Строки=Корень.Строки.НайтиСтроки(Новый Структура("ЭтоГруппа",Истина),Ложь);
Для каждого Стр из Строки Цикл
Range = Лист.Range(Лист.Cells(НомерСтроки, НомерКолонкиКода), Лист.Cells(НомерСтроки, 6));
Range.Merge();
Range.Value = Стр.Наименование;
Range.Font.Name = "Baskerville Old Face";
Range.Font.Size = 16-Стр.Уровень();
Range.IndentLevel = Стр.Уровень();
Range.Font.Bold = 1;
НомерСтроки=НомерСтроки+1;
ВыгрузитьСтроки(Стр,Стр.Уровень());
КонецЦикла;
Строки=Корень.Строки.НайтиСтроки(Новый Структура("ЭтоГруппа",Ложь),Ложь);
Для каждого Стр из Строки Цикл
//Лист.Cells(НомерСтроки,1).Value=Стр.Наименование;
//Лист.Cells(НомерСтроки,2).Value=Стр.Цена;
Лист.Cells(НомерСтроки, НомерКолонкиКода).Value = Стр.Код;
Лист.Cells(НомерСтроки, НомерКолонкиНаименования).Value = Стр.НаименованиеПолное;
Лист.Cells(НомерСтроки, НомерКолонкиНаименования).IndentLevel = Стр.Уровень();
Если стрДлина(Стр.СсылкаUrl)>0 тогда
Лист.Hyperlinks.Add(Лист.Cells(НомерСтроки, НомерКолонкиНаименования),Стр.СсылкаUrl,Стр.НаименованиеПолное);
КонецЕсли;
Лист.Cells(НомерСтроки, НомерКолонкиЦены).NumberFormat ="# ##0,00";
Лист.Cells(НомерСтроки, НомерКолонкиЦены).Value = Стр.Цена;
Лист.Cells(НомерСтроки, НомерКолонкиГарантия).NumberFormat = "0";
Лист.Cells(НомерСтроки, НомерКолонкиГарантия).Value = Стр.Гарантия;
Range = Лист.Range(Лист.Cells(НомерСтроки, 2), Лист.Cells(НомерСтроки, 6));
Range.Font.Name = "Arial";
Range.Font.Size = 8;
Если Стр.Изменение тогда
Range.Font.Bold = 1;
КонецЕсли;
Если НомерСтроки%2 тогда
Range. Interior.Color = rgb(227,237,249);
КонецЕсли;
Лист.Cells(НомерСтроки, НомерКолонкиЗаказ).NumberFormat = "0";
Лист.Cells(НомерСтроки, НомерКолонкиЗаказ).Interior.Color = rgb(218,238,243);
НомерСтроки=НомерСтроки+1;
КонецЦикла;
Если (Уровень>=0) и (НомерСтроки>НачСтрока) Тогда
Лист.Range(Лист.Cells(НачСтрока,1),Лист.Cells(НомерСтроки-1,2)).Rows.Group();
КонецЕсли;
МаксУровней = Макс(Уровень,МаксУровней);
КонецПроцедуры
Функция ОграничениеЗапросаПоНоменклатуре(ВнЗапрос)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураДляПрайсаСрезПоследних.Номенклатура КАК Номенклатура,
| НоменклатураДляПрайсаСрезПоследних.Отбор КАК Отбор
|ИЗ
| РегистрСведений.НоменклатураДляПрайса.СрезПоследних(&ДатаФормированияПрайса, Активен) КАК НоменклатураДляПрайсаСрезПоследних";
Запрос.УстановитьПараметр("ДатаФормированияПрайса", ДатаФормированияПрайса);
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
СтрокаОтбора = "И ( ";
Первый = Истина;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
//ПредопределенноеЗначение(Перечисления.ОтборВЗапросах.Равно)
Ун = СтрЗаменить(ВыборкаДетальныеЗаписи.Номенклатура.УникальныйИдентификатор(),"-","");
СтрокаПараметра = "Отбор"+Ун;//.Наименование;// + ВыборкаДетальныеЗаписи.Отбор; // Пока не важно так как 1 значение в регистре
ВнЗапрос.УстановитьПараметр(СтрокаПараметра,ВыборкаДетальныеЗаписи.Номенклатура);
Если Первый тогда
БулеваяОперация = "";
Первый = Ложь;
Иначе
БулеваяОперация = " ИЛИ ";
КонецЕсли;
СтрокаОтбора = СтрокаОтбора +БулеваяОперация+ " (Номенклатура.Ссылка " + ВыборкаДетальныеЗаписи.Отбор + " (&" + СтрокаПараметра + "))";
КонецЦикла;
СтрокаОтбора = СтрокаОтбора + ")";
ВнЗапрос.Текст = СтрЗАменить(ВнЗапрос.Текст,"//Добавление отбора",СтрокаОтбора);
КонецФункции
Процедура КнопкаВыполнитьНажатие(Кнопка)
Попытка
Ексель = Новый COMОбъект("Excel.Application");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
конецПопытки;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ПОМЕСТИТЬ СправочникНоменклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| (НЕ Номенклатура.ЭтоГруппа)
| И ИСТИНА //Добавление отбора
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура,
| ТоварыНаСкладахОстатки.КоличествоОстаток,
| ЦеныНоменклатурыСрезПоследних.Цена,
| ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры
|ПОМЕСТИТЬ Начало
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &ТекДата,
| Склад В (&Склад)
| И Номенклатура В
| (ВЫБРАТЬ
| СправочникНоменклатура.Ссылка
| ИЗ
| СправочникНоменклатура КАК СправочникНоменклатура)) КАК ТоварыНаСкладахОстатки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
| &ТекДата,
| ТипЦен = &ТипЦен
| И Валюта = &Валюта) КАК ЦеныНоменклатурыСрезПоследних
| ПО ТоварыНаСкладахОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
| И ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры = ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Начало.Номенклатура,
| Начало.КоличествоОстаток,
| Начало.Цена,
| Начало.ХарактеристикаНоменклатуры,
| ВЫБОР
| КОГДА ЦеныНоменклатурыСрезПоследних.Цена = Начало.Цена
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК Изменение
|ПОМЕСТИТЬ ТблИзмЦен
|ИЗ
| Начало КАК Начало
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
| ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, -1),
| ТипЦен = &ТипЦен
| И Валюта = &Валюта) КАК ЦеныНоменклатурыСрезПоследних
| ПО Начало.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
| И Начало.ХарактеристикаНоменклатуры = ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка
|ПОМЕСТИТЬ ТблПриходов
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, -1) И &ТекДата
| И ПоступлениеТоваровУслуг.Проведен
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТблИзмЦен.Номенклатура,
| ТблИзмЦен.КоличествоОстаток,
| ТблИзмЦен.Цена,
| ТблИзмЦен.ХарактеристикаНоменклатуры,
| ВЫБОР
| КОГДА СУММА(ЕСТЬNULL(ПоступлениеТоваровУслугТовары.Количество, 0)) > 0
| ТОГДА ИСТИНА
| ИНАЧЕ ТблИзмЦен.Изменение
| КОНЕЦ КАК Изменение
|ПОМЕСТИТЬ ИтоговаяТбл
|ИЗ
| ТблИзмЦен КАК ТблИзмЦен
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
| ПО ТблИзмЦен.Номенклатура = ПоступлениеТоваровУслугТовары.Номенклатура
| И ТблИзмЦен.ХарактеристикаНоменклатуры = ПоступлениеТоваровУслугТовары.ХарактеристикаНоменклатуры
| И (ПоступлениеТоваровУслугТовары.Ссылка В
| (ВЫБРАТЬ
| ТблПриходов.Ссылка
| ИЗ
| ТблПриходов КАК ТблПриходов))
| И (ПоступлениеТоваровУслугТовары.Склад В (&Склад))
|
|СГРУППИРОВАТЬ ПО
| ТблИзмЦен.Номенклатура,
| ТблИзмЦен.КоличествоОстаток,
| ТблИзмЦен.Цена,
| ТблИзмЦен.ХарактеристикаНоменклатуры,
| ТблИзмЦен.Изменение
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ИтоговаяТбл.Номенклатура КАК Номенклатура,
| ИтоговаяТбл.КоличествоОстаток,
| ИтоговаяТбл.Цена,
| ИтоговаяТбл.ХарактеристикаНоменклатуры,
| ИтоговаяТбл.Изменение,
| ИтоговаяТбл.Номенклатура.СсылкаUrl КАК СсылкаUrl,
| ЗначенияСвойствОбъектов.Значение КАК Гарантия,
| ИтоговаяТбл.Номенклатура.Код КАК Код,
| ИтоговаяТбл.Номенклатура.НаименованиеПолное КАК НаименованиеПолное,
| ИтоговаяТбл.Номенклатура.Наименование КАК Наименование,
| ИтоговаяТбл.Номенклатура.ЭтоГруппа КАК ЭтоГруппа
|ИЗ
| ИтоговаяТбл КАК ИтоговаяТбл
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
| ПО ИтоговаяТбл.Номенклатура = ЗначенияСвойствОбъектов.Объект
| И (ЗначенияСвойствОбъектов.Свойство = ЗНАЧЕНИЕ(ПланВидовХарактеристик.СвойстваОбъектов.Гарантия))
|ГДЕ
| ИСТИНА
|ИТОГИ ПО
| Номенклатура ТОЛЬКО ИЕРАРХИЯ
|АВТОУПОРЯДОЧИВАНИЕ";
ОграничениеЗапросаПоНоменклатуре(Запрос);
Запрос.УстановитьПараметр("ТекДата",ДатаФормированияПрайса);
Запрос.УстановитьПараметр("ТипЦен",Справочники.ТипыЦенНоменклатуры.НайтиПоКоду("000000020"));
Запрос.УстановитьПараметр("Валюта",Константы.ВалютаУправленческогоУчета.Получить());
СписокСкладов = Новый СписокЗначений;
СписокСкладов.Добавить(Справочники.Склады.НайтиПоКоду("002200001")); //Центральный склад
СписокСкладов.Добавить(Справочники.Склады.НайтиПоКоду("002500019")); //Футляры Центральный склад
Запрос.УстановитьПараметр("Склад",СписокСкладов);
Результат = Запрос.Выполнить();
Ексель.DisplayAlerts=Ложь;
Ексель.Visible = ложь;
Книга = Ексель.Workbooks.Add();
Лист = Книга.WorkSheets(1);
Лист.Select();
Ексель.Application.ActiveWindow.SplitRow = 4;
Ексель.Application.ActiveWindow.FreezePanes = 1;
Коеф = 27;
кнопка1 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1", , , , , , , 3, 3, 80, 20);
кнопка1.Name = "Свернуть";
кнопка1.TextFrame.Characters().Text = "Свернуть";
кнопка2 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1", , , , , , , 100, 3, 80, 20);
кнопка1.Name = "ПоказатьВсе";
кнопка1.Name = "КнопкаСвернуть";
кнопка1.Caption = "Свернуть";
кнопка1 = Книга.WorkSheets(1).Buttons.Add(100, 3, 80, 20);
кнопка1.Name = "КнопкаСвернуть";
кнопка1.Caption = "Свернуть";
кнопка1 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1",,,,,,,3, 3, 80, 25);
кнопка1.Name = "КнопкаПоказатьВсе";
Книга.WorkSheets(1).oleobjects(1).Object.Caption = "Показать все";
ст = "Sub Main()
|MsgBox(""Hello, World!"") ' Display message on computer screen.
|End Sub";
Ексель.VBE.ActiveVBProject.VBComponents.Add (1);
Ексель.VBE.ActiveVBProject.VBComponents.Item(1).CodeModule.InsertLines (1, ст);
Ексель.Application.Save();
кнопка2 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1",,,,,,,100, 3, 80, 25);
кнопка2.Name = "КнопкаСвернуть";
Книга.WorkSheets(1).oleobjects(2).Object.Caption = "Свернуть все" ;
кнопка2 = Книга.WorkSheets(1).Buttons.Add(3, 3, 80, 20);
кнопка2.Name = "КнопкаПоказатьВсе";
кнопка2.Caption = "Показать все";
Лист.Outline.SummaryRow = 0;
// { Master 25.11.2011 17:52:33 Прайс-лист
Range = Лист.Range(Лист.Cells(1, 2), Лист.Cells(1, 6));
Range.Merge();
Range.Value = "Прайс-лист";
Range.Font.Name = "Courier New";
Range.Font.Size = 22;
Range.HorizontalAlignment =3;
Range.VerticalAlignment =2;
// }
Лист.Cells(2, 2).Value = "Цены указаны на "+ Формат(ДатаФормированияПрайса,"ДФ=dd.MM.yyyy");
Лист.Cells(2, 2).Name = "Arial";
Лист.Cells(2, 2).Font.Size = 8;
НомерСтроки = 5;
НомерКолонкиНаименования = 3;
НомерКолонкиКода = 2;
НомерКолонкиЦены = 4;
НомерКолонкиГарантия = 5;
НомерКолонкиЗаказ = 6;
// { Master 25.11.2011 17:52:33 Название номенклатура
Range = Лист.Range(Лист.Cells(3, НомерКолонкиКода), Лист.Cells(4, НомерКолонкиКода));
Range.Merge();
Range.Value = "Код";
// }
// { Master 25.11.2011 17:52:33 Название номенклатура
Range = Лист.Range(Лист.Cells(3, НомерКолонкиНаименования), Лист.Cells(4, НомерКолонкиНаименования));
Range.Merge();
Range.Value = "Номенклатура";
// }
// { Master 25.11.2011 17:52:56
Range = Лист.Range(Лист.Cells(3, НомерКолонкиЦены), Лист.Cells(4, НомерКолонкиЦены));
Range.Merge();
Range.Value = "Цена";
// }
// { Master 25.11.2011 17:52:56
Range = Лист.Range(Лист.Cells(3, НомерКолонкиГарантия), Лист.Cells(4, НомерКолонкиГарантия));
Range.Merge();
Range.Value = "Гарантия (мес.)";
Range.WrapText = Истина;
// }
// { Master 25.11.2011 17:52:56
Range = Лист.Range(Лист.Cells(3, НомерКолонкиЗаказ), Лист.Cells(4, НомерКолонкиЗаказ));
Range.Merge();
Range.Value = "Заказ";
// }
Range = Лист.Range(Лист.Cells(3, 2), Лист.Cells(4, 6));
Range.Font.Name = "Arial Narrow";
Range.Font.Size = 12;
Range.HorizontalAlignment =3;
Range.VerticalAlignment =2;
Range.Borders(1).Weight = 2;
Range.Borders(2).Weight = 2;
Range.Borders(3).Weight = 2;
Range.Interior.Color = rgb(54,96,146);
Range.Font.Color = rgb(255,255,255);
Лист.Columns(1).ColumnWidth = 3;
Лист.Columns(НомерКолонкиКода).ColumnWidth = 11;
Лист.Columns(НомерКолонкиНаименования).ColumnWidth = 80;
Лист.Columns(НомерКолонкиЦены).ColumnWidth = 15;
Лист.Columns(НомерКолонкиГарантия).ColumnWidth = 7.86;
Лист.Columns(НомерКолонкиЗаказ).ColumnWidth = 12;
Дерево=Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ВыгрузитьСтроки(Дерево,-1);
Range = Лист.Range(Лист.Cells(5, 2), Лист.Cells(НомерСтроки-1, 6));
Range.Borders(1).Weight = 2;
Range.Borders(2).Weight = 2;
Range.Borders(3).Weight = 2;
Range.Borders(4).Weight = 2;
//область = Лист.Range(Формат(5,"ЧГ=0")+":"+Формат(НомерСтроки,"ЧГ=0"));
//область.Rows.Group();
//Лист.Outline.ShowLevels(2);
//Лист.Outline.ShowLevels(1);
Книга.SaveAs("c:\work\Price_"+Формат(ДатаФормированияПрайса,"ДФ=yyyy-MM-dd")+".xls",56);
Книга.Close();
Ексель.Quit();
КонецПроцедуры
МаксУровней = -1;
//ДатаФормированияПрайса = Дата(2011,11,1);
ДатаФормированияПрайса = ТекущаяДата();
Добавление кнопок в Excel средствами 1с8
Попытка
Ексель = Новый COMОбъект("Excel.Application");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
конецПопытки;
Ексель.DisplayAlerts=Ложь;
Ексель.Visible = ложь;
Книга = Ексель.Workbooks.Add();
Лист = Книга.WorkSheets(1);
Лист.Select();
Ексель.Application.ActiveWindow.SplitRow = 4;
Ексель.Application.ActiveWindow.FreezePanes = 1;
кнопка1 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1", , , , , , , 3, 3, 80, 20);
кнопка1.Name = "Свернуть";
кнопка1.TextFrame.Characters().Text = "Свернуть";
кнопка2 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1", , , , , , , 100, 3, 80, 20);
кнопка1.Name = "ПоказатьВсе";
кнопка1.Name = "КнопкаСвернуть";
кнопка1.Caption = "Свернуть";
кнопка1 = Книга.WorkSheets(1).Buttons.Add(100, 3, 80, 20);
кнопка1.Name = "КнопкаСвернуть";
кнопка1.Caption = "Свернуть";
кнопка1 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1",,,,,,,3, 3, 80, 25);
кнопка1.Name = "КнопкаПоказатьВсе";
Книга.WorkSheets(1).oleobjects(1).Object.Caption = "Показать все";
ст = "Sub Main()
|MsgBox(""Hello, World!"") ' Display message on computer screen.
|End Sub";
Ексель.VBE.ActiveVBProject.VBComponents.Add (1);
Ексель.VBE.ActiveVBProject.VBComponents.Item(1).CodeModule.InsertLines (1, ст);
Ексель.Application.Save();
кнопка2 = Книга.WorkSheets(1).Shapes.AddOLEObject("Forms.CommandButton.1",,,,,,,100, 3, 80, 25);
кнопка2.Name = "КнопкаСвернуть";
Книга.WorkSheets(1).oleobjects(2).Object.Caption = "Свернуть все" ;
кнопка2 = Книга.WorkSheets(1).Buttons.Add(3, 3, 80, 20);
кнопка2.Name = "КнопкаПоказатьВсе";
кнопка2.Caption = "Показать все";
Wednesday, October 26, 2011
mssql конвертация из binary в char и обратно
declare @bina binary(16)
declare @bina1 binary(16)
set @bina=newid();
select @bina
select CONVERT(char(34), @bina, 1)
set @bina1 = Convert(binary(16), CONVERT(char(34), @bina, 1),1)
select @bina1
Tuesday, October 11, 2011
КАКИМ ДОЛЖЕН БЫТЬ ИТ-ДИРЕКТОР
КАКИМ ДОЛЖЕН БЫТЬ ИТ-ДИРЕКТОР
Трушкин Сергей Юрьевич,
Тренер-консультант по вопросам ИТ стратегии и управления ИТ службами,
http://inforoad.ru/trushkin/
Уважаемый менеджер по управлению персоналом, коллега.
В настоящее время Вы находитесь в поиске главного компьютерщика, ИТ директора. Данная статья, быть может, сделает Ваш выбор эффективнее, и, как следствие, улучшит работу компании. Было бы здорово, найти такого, чтобы не возвращаться к этой теме много лет.
Сразу скажу, задача не из легких и вот перечень фактов и идей, обосновывающих мою позицию.
Недавно вышла книга, жестко критикующая всех ИТ-шников. До книги было исследование американского института проектного менеджмента показавшее, что 78% внедрений комплексных систем автоматизации, их еще иногда называют ERP, признаны не достигшими своих целей. Представьте себе, приходит компьютерщик к Вашему директору и говорит «Это стоит сто тысяч, но с вероятностью 78% мы не сделаем того, что вам нужно». Игра в казино на чет/нечет дает вероятность примерно 50%.
Человек поступает в институт на специальность "программист". Если на третьем курсе он не начал продавать сотовые телефоны, или не занялся дизайном интернет-сайтов, а к пятому курсу его из-за компьютера палкой не выгнать, то это асоциальная личность, не любящая людей, считающая, что все беды с сетью из-за глупых юзеров. Кто-то меняется в лучшую сторону, кто-то продолжает деградировать в плане социального интеллекта. Почему это происходит, дает нам понять следующий пункт.
А Вы вообще пытались задуматься, что именно делает администратор, программист, ИТ-директор? Они все время что-то делают, компьютеры и программы все время выходят из строя, почта не работает в самые важные моменты, картриджи в принтерах заканчиваются на распечатке самого важного документа компании. Нет! Причина в том, что область знаний слишком специальная, каждый, повторяю, каждый менеджер не компьютерщик думает, что компьютеры это китайская грамота, проникшая в мозг гения с молоком матери, и то, что все работает как попало, подтверждает таинственную сложность этой работы. Итак, кратко пункт три звучит следующим образом – компьютерщика НИКТО в компании не контролирует. Это называется диктат узкого специалиста. Вот об области HR каждый может высказаться, все специалисты у всех есть мнения по оценке эффективности! А неэффективность компьютерщика оказывается видна только по прошествии месяцев или лет. Вам на заметку способ оценки: Самый лучший компьютерщик вообще ничего не делает, все делают компьютеры. У плохого компьютерщика всегда аврал и он нарасхват.
Каким бы асоциальным компьютерщик не был, но их много и у них есть свое сообщество. В этом сообществе большинство любят проявлять свое эго рассказом о своих достижениях: крутизне компьютера на своем столе, количестве террабайт на корпоративном сервере, ценой коммуникационного оборудования, крутизной закупленной системы. Никто не хвастается объемом сэкономленных компании средств. Есть такая странная мысль, что закупка дорогой системы автоматизации нужна компьютерщику для еще одной «крутой» строки в резюме. Кто из Вас интересуется судьбой всех крутых проектов, в которых участвовал соискатель? И если они провалились то фраза: «компания была не готова» воспринимается как норма. Ваша компания, конечно, не такая, ваша компания готова, а специалист очень хороший, поскольку резюме пестрит крутыми системами! ...Я же и не спорю. За одного битого, двух не битых дают. Опыт приходит с ошибками, но ошибка должна быть осознана, иначе она не развивает. Корректнее была бы фраза соискателя: «Проект провалился, поскольку я не осознал, что компания не готова к переменам, но сейчас я знаю, как это проверять….».
В компании всегда есть один топ-менеджер, который на компьютерщика молится и несколько, которые его тихо или громко, скажем так, критикуют. Молится тот, кто ЖДЕТ, когда ему сделают то, что он попросил, и чем ИТ-директор занимается как раз сейчас, а остальные либо не получили ничего, либо получили нечто, чем нельзя пользоваться, однако оказались сами виноваты. Вы просили так, мы сделали так, оказалось, не работает, мы не виноваты, что вы не правильно просили! И что делать генеральному директору в такой ситуации? Неужели учить всех сотрудников компании, пониманию возможностей и ограничений связки компьютер-человек для правильной постановки задачи? Или все же ИТ директор должен нести ответственность и за конечный результат и планировать его не меньше внутреннего заказчика, а может даже больше! Каждый раз, доказывая эффективность инструмента, которым он пользуется в совершенстве.
Итак, подведем итог. Четыре проблемы:
Социальная неадекватность;
Узкая специализация и отсутствие контроля;
Мотивация на решение функциональных проблем, а не линейных;
Не желание повысить свою квалификацию до уровня участия в планировании результата компании или ее отдела.
И, как следствие, главная проблема отрасли – весьма скромные результаты при огромных вложенных деньгах.
Хотя бы в границах Вашей организации Вы можете улучшить результаты ИТ, сократить издержки. Но для этого вам потребуется адекватный ИТ директор. Далее скажу банальную фразу рыночной экономики – «спрос рождает предложение». Начните спрашивать и начнете получать! Далее о том, что и как спрашивать у компьютерщика.
Сапожник в сапогах. ИТ директор лучше всех понимает, как использовать компьютер для менеджмента. Он же и гений компьютеров и управленец. Он может рассказать Вам о тех программах, которые он использует в своей работе и, может быть, эти знания будут полезны лично Вам. И не только рассказать, а показать! Не может? Странно.
Энциклопедия. Все знать невозможно! Даже в узкой области компьютеризации. Знаете сколько специальных курсов для компьютерщиков? Десятки тысяч. Спросите сколько у него друзей консультантов, каждый из которых, в совершенстве знает какую-то проблему, поскольку он уже убил время на ее решение. В каких профессиональных клубах состоит, какие журналы постоянно выписывает домой. Областей не так много, но около десятка компаний и людей он должен назвать. Деньги. Самый сложный вопрос. По-моему, ИТ директор каждый раз беря деньги в компании обязательно должен сказать, когда и как вернет. Компьютеризация, это всегда способ снижения издержек либо повышения производительности труда. Всегда есть эффект и должен быть анализ результата. Это и есть способ втянуть компьютерщика в решение бизнес задач из области увлеченности терабайтами и мегапикселами.
Еще деньги. Для третьего пункта компьютерщику и Вам ОБЯЗАТЕЛЬНО нужно понять, что «ИТ бюджет» компании, это на 90% деньги НЕ ДЕПАРТАМЕНТА КОМПЬЮТЕРИЗАЦИИ, а других структурных подразделений. Компьютерщики лишь обслуживают «ИТ деньги» компании наиболее эффективным образом. И делать они должны это, оценивая собственную эффективность. И получать зарплату только при фактическом выполнении плана инвестиций в область ИТ с получением ожидаемого эффекта.
Клиентоориентированность. Обеспечив выполнение предыдущего пункта, Вы сможете добиться ситуации, когда ИТ-директор начнет предлагать выгодные инвестиции в автоматизацию работы подразделений. Появится контроль Внутреннего Заказчика. А без этого получается, что деньги компьютерщику дает генеральный директор, а результатами вынуждены пользоваться другие люди, а когда другие говорят, что ничего не получили, генеральный вынужден решать не решаемую задачу - Кто прав, кто виноват? Спасает лишь то, что так почти у всех. Только в современных условиях это больше не пройдет. Если раньше мерилом конкурентного преимущества в ИТ был объем вложенных денег, то при очень быстром удешевлении технологий на первое место выходит то, с какой скоростью, и как качественно были инвестированы деньги компании в область ИТ.
Время = деньги. Забудьте о годах внедрения! Если внедряемая технология не внедрилась за пару месяцев и не принесла ощутимого эффекта в течение года, вы плохо распоряжаетесь своими деньгами. ИТ должен высвобождать время и деньги, в пределах нескольких месяцев, а не потреблять их годами. Потом обычно говорят – «все было хорошо, мы двигались по плану, но на пятом году внедрения компания разорилась, жаль». Мотивация мозгов. Тема очень обширная. С одной стороны компьютерщики полубоги, поэтому и асоциальны, с другой стороны у них есть потребность в общении. Большинство ее выражают через сетевые компьютерные игрушки. Очень серьезная, кстати, болезнь. Выясните, болен ли он, путем восхищения и искренним интересом к его результатам. Если болен, неминуемо начнет воровать время компании. Так вот, ИТ директор должен обладать арсеналом стимулирования своих подчиненных. Самые важные:
Вовлеченность руководства;
Формирование прямой ответственности каждого участника проекта перед Заказчиком;
Мозговые штурмы, свобода и творчество;
Материальное стимулирование выполнения сроков;
Что-то похожее на японские «кружки качества». Все проблемы исправляются за счет того, кто наломал дров вплоть до покрытия возникших денежных потерь. Совместная работа по исправлению и недопущению проблем в будущем, технологизация работы специалистов;
Регламентация, контроль работ и документирование вклада. Ежедневные отчеты об использовании рабочего времени. Обязательная фиксация ВСЕХ запросов в службы и анализ статистики исполнения. Этот пункт кроме мотивации ИТ сотрудников хорошо сказывается на адекватности оценки работы департамента и постоянного повышения качества работы;
Аудит. Не стесняйтесь проверять своих компьютерщиков. Так и впишите в положении о подразделении. Не реже двух раз в год состояние системы, планы и качество оценивают ВНЕШНИЕ компании, желательно конкуренты тех, у кого ваш компьютерщик делает покупки. Отзыв, конечно, может быть слишком критическим, но здесь важен скорее сам факт проверки и возможность вскрытия неэффективности заставляет больше думать и искать лучшие решения. Добейтесь результата хотя бы по двум, трем пунктам и потери уменьшаться, отработайте все пункты и получите лучшее в отрасли подразделение ИТ.
Я еще много могу рассказывать об управлении ИТ. Иногда читаю авторские семинары, учу ИТ директоров и каждый раз собираю статистику, о том кто и что использует. В итоге, пришел к выводу, что лучшими ИТ директорами могут стать Финансовые директоры, поскольку они больше всех вовлечены в управление информационными потоками в силу задачи постановки управленческого учета. Чуть подучить, и в бой. Далее, по моему мнению, ИТ директора можно получить из компьютерщика, развив в нем социальный интеллект и бизнес-мышление. И еще ИТ директором может стать HRM, поскольку он организует часть информационных потоков - общение.
Надеюсь, Вы поможете мне повысить эффективность ИТ отрасли, повысив отдачу от ИТ в своей компании путем грамотного построения и управления ИТ службой. Ну и, конечно, желаю успеха в найме ИТ директора.
Thursday, September 15, 2011
Последняя реализация индексации
SET NOCOUNT ON; DECLARE @objectid int; DECLARE @indexid int; DECLARE @partitioncount bigint; DECLARE @schemaname nvarchar(130); DECLARE @objectname nvarchar(130); DECLARE @indexname nvarchar(130); DECLARE @partitionnum bigint; DECLARE @partitions bigint; DECLARE @frag float; DECLARE @command nvarchar(4000); declare @datetime1 datetime; declare @datetime2 datetime; declare @time time; declare @Rdatetime1 datetime; declare @Rdatetime2 datetime; declare @Rtime time; DECLARE @p_body as nvarchar(max), @p_subject as nvarchar(max) DECLARE @p_recipients as nvarchar(max), @p_profile_name as nvarchar(max) SET @p_profile_name = N'sql' SET @p_recipients = N'dyachok.nickolay@agromars.com; Oleynik@agromars.com' SET @p_subject = N'Отчет по работе с индексами' SET @Rdatetime1 = getdate() SET @p_body = N'Начало отчета:' + CONVERT(nvarchar(30),@Rdatetime1,126)+N'<BR>' BEGIN TRY -- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function -- and convert object and index IDs to names. IF OBJECT_ID('#work_to_do') IS NOT NULL DROP TABLE #work_to_do; SELECT object_id AS objectid, index_id AS indexid, partition_number AS partitionnum, avg_fragmentation_in_percent AS frag INTO #work_to_do FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') WHERE avg_fragmentation_in_percent > 5.0 AND index_id > 0 order by avg_fragmentation_in_percent desc; -- Declare the cursor for the list of partitions to be processed. DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do; -- Open the cursor. OPEN partitions; FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag; -- Loop through the partitions. WHILE (@@FETCH_STATUS = 0) BEGIN; --IF @@FETCH_STATUS < 0 BREAK; SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name) FROM sys.objects AS o JOIN sys.schemas as s ON s.schema_id = o.schema_id WHERE o.object_id = @objectid; SELECT @indexname = QUOTENAME(name) FROM sys.indexes WHERE object_id = @objectid AND index_id = @indexid; SELECT @partitioncount = count (*) FROM sys.partitions WHERE object_id = @objectid AND index_id = @indexid; --PRINT N'Execute: ' + @command -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding. IF @frag < 30.0 SET @command = N'BEGIN TRY ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE END TRY BEGIN CATCH END CATCH;'; IF @frag >= 30.0 SET @command = N'BEGIN TRY ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (ONLINE=ON) END TRY BEGIN CATCH ALTER INDEX '+@indexname+N' ON '+ @schemaname+N'.'+ @objectname+ N' REBUILD WITH (ONLINE=OFF) END CATCH;'; IF @partitioncount > 1 SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10)); set @datetime1 = getdate(); EXEC (@command); set @datetime2 = getdate(); set @time = @datetime2-@datetime1; SET @p_body = @p_body + N'Executed: ' + @command+N' Затрачено время:'+CAST(@time as NvarChar(13))+N'<BR>'; FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag; END; -- Close and deallocate the cursor. CLOSE partitions; DEALLOCATE partitions; -- Drop the temporary table. DROP TABLE #work_to_do; END TRY BEGIN CATCH SET @p_body = @p_body + N'<BR>!!!!Ошибка выполнения:' + ERROR_NUMBER() + N' '+ERROR_SEVERITY() + N' '+ ERROR_STATE()+N' '+ERROR_LINE() + N' ' +ERROR_PROCEDURE() + N' '+ERROR_MESSAGE() END CATCH SET @Rdatetime2 = getdate() set @Rtime = @Rdatetime2-@Rdatetime1; SET @p_body = @p_body + N'Завершение отчета:' + CONVERT(nvarchar(30), @Rdatetime2, 126) + N' Время выполенения:' + CAST(@Rtime as NvarChar(13))+N'<BR>' EXEC msdb.dbo.sp_send_dbmail @profile_name = @p_profile_name, @recipients = @p_recipients, @body = @p_body, @body_format = 'HTML', @subject = @p_subject GO
Новая система по перестройке индексов, совместил скрипт микрософта и гилева, так как скрипт гилева перестал нормально отрабатывать.
Опытным путем установил, что скорость работы базы зависит от частоты индексирования. Сейчас размер базы около 400 ГБ. Индексацию делаю каждый час после backup
Declare @ToFile Nvarchar(256); Declare @Name Nvarchar(256); use agroupp82; set @ToFile=N'd:\Backup\'+db_name()+N'_'+CONVERT(nvarchar(10),getdate(),112)+REPLACE(CONVERT(nvarchar(8),GETDATE(),108),':','')+N'.trn' set @Name=N'log_'+db_name()+N'_'+CONVERT(nvarchar(10),getdate(),112)+REPLACE(CONVERT(nvarchar(8),GETDATE(),108),':','') BACKUP log AGROUPP82 TO disk=@ToFile WITH COMPRESSION, NOFORMAT, NOINIT, NAME=@Name, SKIP, NOREWIND, NOUNLOAD, STATS = 10Связано с тем что очень быстро набивается журнал логов. Ну и как итог сам скрипт:
use agroupp82; SET NOCOUNT ON; DECLARE @objectid int; DECLARE @indexid int; DECLARE @partitioncount bigint; DECLARE @schemaname nvarchar(130); DECLARE @objectname nvarchar(130); DECLARE @indexname nvarchar(130); DECLARE @partitionnum bigint; DECLARE @partitions bigint; DECLARE @frag float; DECLARE @command nvarchar(4000); declare @datetime1 datetime; declare @datetime2 datetime; declare @time time; -- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function -- and convert object and index IDs to names. IF OBJECT_ID('#work_to_do') IS NOT NULL DROP TABLE #work_to_do; SELECT object_id AS objectid, index_id AS indexid, partition_number AS partitionnum, avg_fragmentation_in_percent AS frag INTO #work_to_do FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') WHERE avg_fragmentation_in_percent > 5.0 AND index_id > 0 order by avg_fragmentation_in_percent desc; -- Declare the cursor for the list of partitions to be processed. DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do; -- Open the cursor. OPEN partitions; FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag; -- Loop through the partitions. WHILE (@@FETCH_STATUS = 0) BEGIN; --IF @@FETCH_STATUS < 0 BREAK; SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name) FROM sys.objects AS o JOIN sys.schemas as s ON s.schema_id = o.schema_id WHERE o.object_id = @objectid; SELECT @indexname = QUOTENAME(name) FROM sys.indexes WHERE object_id = @objectid AND index_id = @indexid; SELECT @partitioncount = count (*) FROM sys.partitions WHERE object_id = @objectid AND index_id = @indexid; -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding. IF @frag < 30.0 SET @command = N'BEGIN TRY ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE END TRY BEGIN CATCH END CATCH;'; IF @frag >= 30.0 SET @command = N'BEGIN TRY ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (ONLINE=ON) END TRY BEGIN CATCH ALTER INDEX '+@indexname+N' ON '+ @schemaname+N'.'+ @objectname+ N' REBUILD WITH (ONLINE=OFF) END CATCH;'; IF @partitioncount > 1 SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10)); set @datetime1 = getdate(); --EXEC (@command); set @datetime2 = getdate(); set @time = @datetime2-@datetime1; PRINT N'Executed: ' + @command+N' Затрачено время:'+CAST(@time as NvarChar(13)); FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag; END; -- Close and deallocate the cursor. CLOSE partitions; DEALLOCATE partitions; -- Drop the temporary table. DROP TABLE #work_to_do; GO
Subscribe to:
Posts (Atom)