Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Перем
- мСекции Экспорт,
- Секции,
- мХексЧисла,
- мХексСтроки,
- ТаблицаДанных;
- #Область СлужебныеПроцерурыИФункции
- Функция Byte2Hex(Знач Byte)
- Low = Byte % 16;
- High = (Byte - Low) / 16;
- Возврат Dec2Hex(High)+Dec2Hex(Low);
- КонецФункции
- Функция Dec2Hex(Знач Значение)
- стрХекс = Из_Число_В_XСчисл(Значение, "0123456789ABCDEF");
- Возврат стрХекс;
- КонецФункции
- Функция Hex2Dec(Знач Значение)
- стрХекс = Из_ХСчисл_В_Число(Значение, "0123456789ABCDEF");
- Возврат стрХекс;
- КонецФункции
- // http://infostart.ru/public/70053/
- //
- Функция Из_Число_В_XСчисл(Знач Значение, Шаблон)
- Результат="";
- Основание = СтрДлина(Шаблон);
- Пока Значение>0 цикл
- Остат = Значение%Основание;
- Результат1=Сред(Шаблон,Остат+1,1);
- Значение = (Значение-Остат)/Основание;
- Результат = Результат1 + Результат;
- КонецЦикла;
- Возврат ?(ПустаяСтрока(Результат), Сред(Шаблон, 1, 1), Результат);
- КонецФункции
- // http://infostart.ru/public/95428/
- //
- Функция Из_ХСчисл_В_Число(Знач аф,Шаблон)
- аф = ВРег(аф); // на всякий случай.
- ДлинаШаблона = СтрДлина(Шаблон);
- ДлинаСтроки = СтрДлина(аф);
- Результат = 0;
- Для ТекСимвол = 1 По ДлинаСтроки Цикл
- ОбрабатываемыйСимвол = Сред(аф, ТекСимвол,1);
- ПозицияВШаблоне = Найти(Шаблон,ОбрабатываемыйСимвол)-1;
- Результат = Результат * ДлинаШаблона + ПозицияВШаблоне;
- КонецЦикла;
- Возврат(Результат);
- КонецФункции
- // https://helpf.pro/faq/view/351.html
- //
- Функция РазложитьСтрокуВМассивПодстрок(Знач Строка, Знач Разделитель = ",",
- Знач ПропускатьПустыеСтроки = Истина)
- Результат = Новый Массив;
- // для обеспечения обратной совместимости
- Если ПропускатьПустыеСтроки = Неопределено Тогда
- ПропускатьПустыеСтроки = ?(Разделитель = " ", Истина, Ложь);
- Если ПустаяСтрока(Строка) Тогда
- Если Разделитель = " " Тогда
- Результат.Добавить("");
- КонецЕсли;
- Возврат Результат;
- КонецЕсли;
- КонецЕсли;
- //
- Позиция = Найти(Строка, Разделитель);
- Пока Позиция > 0 Цикл
- Подстрока = Лев(Строка, Позиция - 1);
- Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Подстрока) Тогда
- Результат.Добавить(Подстрока);
- КонецЕсли;
- Строка = Сред(Строка, Позиция + СтрДлина(Разделитель));
- Позиция = Найти(Строка, Разделитель);
- КонецЦикла;
- Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Строка) Тогда
- Результат.Добавить(Строка);
- КонецЕсли;
- Возврат Результат;
- КонецФункции
- Функция СтрПовторить(Знач Строка, КолРаз)
- рез="";
- Для й=1 по КолРаз Цикл
- рез = рез + Строка;
- КонецЦикла;
- Возврат Рез;
- КонецФункции
- // http://forum.infostart.ru/forum24/topic88416/message932315/#message932315
- //
- Процедура ВывестиТаблицуНаФорму(УФ,ИмяТЗНаФорме,ТЗ, ТЗОбработчиковСобытий = Неопределено)
- // СОЗДАНИЕ РЕКВИЗИТОВ ФОРМЫ
- МассивДобавляемыхРеквизитов = Новый Массив;
- Для Каждого Колонка Из ТЗ.Колонки Цикл
- МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения,ИмяТЗНаФорме ,Колонка.Заголовок));
- КонецЦикла;
- МассивУдаляемыхРеквизитов = УФ.ПолучитьРеквизиты(ИмяТЗНаФорме);
- МассивИменУдаляемыхРеквизитов = Новый Массив;
- Для каждого Элемент Из МассивУдаляемыхРеквизитов Цикл
- МассивИменУдаляемыхРеквизитов.Добавить(ИмяТЗНаФорме + "." + Элемент.Имя);
- КонецЦикла;
- УФ.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов,МассивИменУдаляемыхРеквизитов);
- // СОЗДАНИЕ ЭЛЕМЕНТОВ ФОРМЫ
- Для каждого Элемент Из МассивУдаляемыхРеквизитов Цикл
- УдаляемыйЭлемент = УФ.Элементы.Найти(ИмяТЗНаФорме + Элемент.Имя);
- УФ.Элементы.Удалить(УдаляемыйЭлемент);
- КонецЦикла;
- Для Каждого Колонка Из ТЗ.Колонки Цикл
- НоваяКолонка = УФ.Элементы.Добавить(ИмяТЗНаФорме + Колонка.Имя, Тип("ПолеФормы"), УФ.Элементы[ИмяТЗНаФорме]);
- НоваяКолонка.Заголовок = Колонка.Заголовок;
- НоваяКолонка.ПутьКДанным = ИмяТЗНаФорме + "." + Колонка.Имя;
- НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
- НоваяКолонка.РежимРедактирования = РежимРедактированияКолонки.ВходПриВводе;
- НоваяКолонка.МногострочныйРежим = Истина;
- НоваяКолонка.Высота = 1;
- НоваяКолонка.Видимость = НЕ Найти(Колонка.Имя, "Неизвестно"); // отладка
- КонецЦикла;
- //УФ[ИмяТЗНаФорме].Очистить();
- //УФ[ИмяТЗНаФорме].Загрузить(ТЗ);
- УФ.ЗначениеВРеквизитФормы(ТЗ, ИмяТЗНаФорме);
- // Привязка обработчиков событий
- Если ТЗОбработчиковСобытий = Неопределено Тогда
- Возврат;
- КонецЕсли;
- Для Каждого Строка Из ТЗОбработчиковСобытий Цикл
- УФ.Элементы[Строка.ИмяЭлемента].УстановитьДействие(Строка.ИмяСобытия, Строка.ИмяЭлемента + Строка.ИмяСобытия);
- КонецЦикла;
- КонецПроцедуры
- // http://infostart.ru/public/541555/
- //
- Функция ПреобразоватьТекстCSVвТЗ(ТекстCSV="", Разделитель=";") Экспорт
- ТЗ = Новый ТаблицаЗначений;
- ОсобаяСтрока = "$#%^&*!xyxb$#%&*!^"; // для замены ""
- НомерСтроки = 1;
- Стр = СтрПолучитьСтроку(ТекстCSV,НомерСтроки);
- Пока НомерСтроки <= СтрЧислоСтрок(ТекстCSV) Цикл
- СтрокаТЗ = ТЗ.Добавить();
- НомерПоля = 0;
- Пока Стр <> "" Цикл
- Токен = "";
- ПозицияРазделителя = Найти(стр, Разделитель);
- ПозицияОткрКавычек = Найти(стр, """");
- Если (ПозицияРазделителя > ПозицияОткрКавычек ИЛИ ПозицияРазделителя = 0) И ПозицияОткрКавычек > 0 Тогда
- // начинающееся с кавычек читаем до тех пор
- Токен = Сред(Стр, 1, ПозицияОткрКавычек);
- Стр = СтрЗаменить(Сред(Стр, ПозицияОткрКавычек+1), """""", ОсобаяСтрока);
- ПозицияЗакрКавычек = Найти(Стр, """");
- Пока ПозицияЗакрКавычек = 0 Цикл
- Токен = Токен + Стр + Символы.ПС;
- НомерСтроки = НомерСтроки + 1;
- Стр = СтрПолучитьСтроку(ТекстCSV, НомерСтроки);
- Стр = СтрЗаменить(Стр, """""", ОсобаяСтрока);
- // пока не встретим закрывающие
- ПозицияЗакрКавычек = Найти(Стр, """");
- КонецЦикла;
- ПозицияРазделителя=Найти(Сред(Стр,ПозицияЗакрКавычек), Разделитель);
- ПозицияРазделителя = ?(ПозицияРазделителя>0, ПозицияЗакрКавычек + ПозицияРазделителя-1, 0);
- КонецЕсли;
- Токен = Токен + ?(ПозицияРазделителя>0, Сред(Стр, 1, ПозицияРазделителя-1), Стр);
- Стр = ?(ПозицияРазделителя>0, Сред(Стр, ПозицияРазделителя+1), "");
- Если Лев(Токен, 1) = """" Тогда
- Токен = Сред(Токен, 2);
- Токен = ?(Прав(Токен, 1) = """", Сред(Токен, 1, СтрДлина(Токен)-1), Токен);
- КонецЕсли;
- Токен = СтрЗаменить(Токен, ОсобаяСтрока, """");
- НомерПоля = НомерПоля + 1;
- Если ТЗ.Колонки.Количество()<НомерПоля Тогда
- ТЗ.Колонки.Добавить("Колонка"+НомерПоля, Новый ОписаниеТипов("Строка"));
- КонецЕсли;
- СтрокаТЗ[НомерПоля-1] = Токен;
- КонецЦикла;
- НомерСтроки = НомерСтроки + 1;
- Стр = СтрПолучитьСтроку(ТекстCSV, НомерСтроки);
- КонецЦикла;
- Возврат ТЗ;
- КонецФункции
- // http://infostart.ru/public/541555/
- //
- Функция ПреобразоватьТЗвТекстCSV(ТЗ, Разделитель = ";", флЭкспортироватьИменаКолонок = Ложь)
- ТекстCSV = "";
- Если флЭкспортироватьИменаКолонок Тогда
- //Если нужно выгружать наименование колонок Выгружаем
- ПодготовленнаяСтрока = "";
- Для Каждого Колонка Из ТЗ.Колонки Цикл
- ПодготовленнаяСтрока = ПодготовленнаяСтрока + Колонка.Имя + Разделитель;
- КонецЦикла;
- ПодготовленнаяСтрока = Лев (ПодготовленнаяСтрока,СтрДлина(ПодготовленнаяСтрока)-1);
- ТекстCSV = ТекстCSV + ПодготовленнаяСтрока + Символы.ПС;
- КонецЕсли;
- Для Каждого Строка Из ТЗ Цикл
- ПодготовленнаяСтрока = "";
- Для Каждого Колонка Из ТЗ.Колонки Цикл
- ПреобразованноеПоле = Строка[Колонка.Имя];
- //по правилам CSV если поле содержит двойные ковычки они должны повторятся дважды
- Если Найти(ПреобразованноеПоле,"""") Тогда
- ПреобразованноеПоле = СтрЗаменить(ПреобразованноеПоле,"""","""""");
- КонецЕсли;
- //по правилам CSV если поле содержит перенос строки или запятую оно должно заключатся в двойные кавычки
- Если Найти(ПреобразованноеПоле,Разделитель) ИЛИ Найти(ПреобразованноеПоле,Символы.ПС) ИЛИ Найти(ПреобразованноеПоле,"""") Тогда
- ПреобразованноеПоле = """" + ПреобразованноеПоле + """";
- КонецЕсли;
- ПодготовленнаяСтрока = ПодготовленнаяСтрока + ПреобразованноеПоле + Разделитель;
- КонецЦикла;
- ПодготовленнаяСтрока = Лев (ПодготовленнаяСтрока,СтрДлина(ПодготовленнаяСтрока)-1);
- ТекстCSV = ТекстCSV + ПодготовленнаяСтрока + Символы.ПС;
- КонецЦикла;
- Возврат ТекстCSV;
- КонецФункции
- #КонецОбласти
- Функция НоваяСекция(Смещение, Размер, ТипУпаковки="", ИмяСекции="", ЗначениеПоУмолчанию=0, Расшифровка = "")
- Возврат Новый Структура("Смещение, ИмяСекции, Размер, ТипУпаковки, Расшифровка, ЗначениеПоУмолчанию", Смещение, ИмяСекции, Размер, ТипУпаковки, РазложитьСтрокуВМассивПодстрок(Расшифровка, ","), ЗначениеПоУмолчанию);
- КонецФункции
- Функция ЗаписатьМассивПолезныхБайтВФайлRPB(МассивБайт)
- // магия
- КоличествоБайт = МассивБайт.Количество();
- КоличествоСтраниц = Окр( (КоличествоБайт-25)/(6138*128+128)+0.5, 0, РежимОкругления.Окр15как10 );
- КоличествоЗаписей = ((КоличествоБайт-25)-128*КоличествоСтраниц)/6138;
- ТекстФайла = "";
- // подготовим заготовки для секций типа "Строка" и ""
- Заготовки = Новый Структура;
- Для й=0 по мСекции.Количество()-1 Цикл
- Если мСекции[й].ТипУпаковки = "" Тогда
- Заготовка = "";
- Для Каждого ХексСтр из РазложитьСтрокуВМассивПодстрок(мСекции[й].ЗначениеПоУмолчанию, " ") Цикл
- ТекБайт = мХексЧисла[ХексСтр];
- Заготовка = Заготовка + Символ(ТекБайт);
- КонецЦикла;
- Заготовки.Вставить(мСекции[й].ИмяСекции, Заготовка);
- ИначеЕсли мСекции[й].ТипУпаковки="Строка" Тогда
- Заготовка = СтрПовторить(Символ(0), мСекции[й].Размер);
- Заготовки.Вставить(мСекции[й].ИмяСекции, Заготовка);
- КонецЕсли;
- КонецЦикла;
- // запишем заголовок
- Для й=0 по 25-1 Цикл
- ТекстФайла = ТекстФайла + Символ(МассивБайт[й]);
- КонецЦикла;
- // пишем только значащие данные
- Для й=0 По КоличествоЗаписей-1 Цикл
- НомерСтраницы = Цел((й)/128)+1;
- АдресСегмента = 25+НомерСтраницы*128+й*6138;
- СтрокаСегмента = "";
- // для каждой секции
- Для ц=0 По мСекции.Количество()-1 Цикл
- Если мСекции[ц].ТипУпаковки = "" Тогда
- // НеизвСекцияА и НеизвСекцияБ возьмем из ЗначениеПоУмолчанию
- СтрокаСегмента = СтрокаСегмента + Заготовки[мСекции[ц].ИмяСекции];
- ИначеЕсли мСекции[ц].ТипУпаковки = "Строка" Тогда
- // строки уже оканчиваются null-байтом
- Для сч=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
- ТекБайт = МассивБайт[сч];
- Если ТекБайт <> Неопределено Тогда
- СтрокаСегмента = СтрокаСегмента + Символ(ТекБайт);
- Иначе
- Прервать;
- КонецЕсли;
- КонецЦикла;
- // поэтому дополняем нулями
- СтрокаСегмента = СтрокаСегмента + Сред(Заготовки[мСекции[ц].ИмяСекции], сч-(АдресСегмента+мСекции[ц].Смещение)+1);
- Иначе
- // остальные пишем полностью
- Для сч=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
- ТекБайт = МассивБайт[сч];
- СтрокаСегмента = СтрокаСегмента + Символ(?(ТекБайт=Неопределено, 0, ТекБайт));
- КонецЦикла;
- КонецЕсли;
- КонецЦикла;
- ИндексСтраницы = ?(й%128=0, Лев( СтрПовторить(Символ(1), КоличествоЗаписей-й) + СтрПовторить(Символ(0), 128), 128 ), "");
- ТекстФайла = ТекстФайла + ИндексСтраницы + СтрокаСегмента;
- КонецЦикла;
- // ТекстФайла -> ДД
- ИмяВремФайла = ПолучитьИмяВременногоФайла(".rpb");
- ТекстПостроитель = Новый ЗаписьXML;
- ТекстПостроитель.ОткрытьФайл(ИмяВремФайла,"ISO-8859-1");
- ТекстПостроитель.ЗаписатьБезОбработки(ТекстФайла); // #13#10 !
- ТекстПостроитель.Закрыть();
- ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВремФайла);
- УдалитьФайлы(ИмяВремФайла);
- Возврат ДвоичныеДанныеФайла;
- КонецФункции
- Функция ПолучитьМассивПолезныхБайтИзФайлаRPB(ДвоичныеДанныеФайла)
- // ДД -> ТекстФайла
- ИмяВремФайла = ПолучитьИмяВременногоФайла(".rpb");
- ДвоичныеДанныеФайла.Записать(ИмяВремФайла);
- ТекстовыйДокумент = Новый ТекстовыйДокумент;
- ТекстовыйДокумент.Прочитать(ИмяВремФайла, "ISO-8859-1", "");
- ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
- УдалитьФайлы(ИмяВремФайла);
- // магия
- МассивБайт = Новый Массив(СтрДлина(ТекстФайла));
- КоличествоБайт = МассивБайт.Количество();
- КоличествоСтраниц = Окр( (КоличествоБайт-25)/(6138*128+128)+0.5, 0, РежимОкругления.Окр15как10 );
- КоличествоЗаписей = ((КоличествоБайт-25)-128*КоличествоСтраниц)/6138;
- NullСимвол = Символ(0);
- // читаем только значащие данные
- Для й=0 по КоличествоЗаписей-1 Цикл
- НомерСтраницы = Цел((й)/128)+1;
- АдресСегмента = 25+НомерСтраницы*128+й*6138;
- // для каждой секции
- Для ц=0 По мСекции.Количество()-1 Цикл
- Если мСекции[ц].ТипУпаковки = "" Тогда
- // НеизвСекцияА и НеизвСекцияБ пропускаем
- Продолжить;
- ИначеЕсли мСекции[ц].ТипУпаковки = "Строка" Тогда
- // строки считываем до null-term симола (2 нулевых байта)
- Для ы=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
- ТекСимвол = Сред(ТекстФайла, ы+1, 1);
- Если (ы+1)%2=0 И ТекСимвол = NullСимвол Тогда
- Прервать;
- Иначе
- МассивБайт[ы] = КодСимвола(ТекСимвол);
- КонецЕсли;
- КонецЦикла;
- Иначе
- // числа - считаем все 4 байта, булево - 2
- Для ы=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
- ТекСимвол = Сред(ТекстФайла, ы+1, 1);
- МассивБайт[ы] = КодСимвола(ТекСимвол);
- КонецЦикла;
- КонецЕсли;
- КонецЦикла;
- КонецЦикла;
- Возврат МассивБайт;
- КонецФункции
- Функция РаспаковатьДанные(МассивБайт, АдресСегмента, Секция)
- АдресСекции = АдресСегмента + Секция.Смещение;
- Если Найти(Секция.ИмяСекции, "Неизвестно") > 0 Тогда
- Возврат Неопределено; // отладка
- КонецЕсли;
- Если Секция.ТипУпаковки="Число" Тогда
- Число = МассивБайт[АдресСекции+1]*256 + МассивБайт[АдресСекции]; // 16-bit unsigned integer WORD
- Возврат Число;
- ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
- Флаг = МассивБайт[АдресСекции]=1;
- Возврат Флаг;
- ИначеЕсли Секция.ТипУпаковки="Строка" Тогда
- Строка = "";
- Для й=0 по Секция.Размер/2-1 Цикл
- МладшийБайт = МассивБайт[АдресСекции+й*2];
- СтаршийБайт = МассивБайт[АдресСекции+й*2+1];
- Если МладшийБайт=Неопределено Тогда Прервать; КонецЕсли;
- КодСимвола = СтаршийБайт*256 + МладшийБайт; // 2-byte utf 8 char
- Если КодСимвола>0 Тогда
- Строка = Строка + Символ(КодСимвола);
- Иначе
- Прервать; // null terminated string
- КонецЕсли;
- КонецЦикла;
- Возврат Строка;
- Иначе
- СтрокаХекс = "";
- Для й=0 по Секция.Размер-1 Цикл
- Байт = МассивБайт[АдресСекции+й];
- СтрокаХекс = СтрокаХекс + мХексСтроки[Байт] + ?((й+1)%16, " ", Символы.ПС);
- КонецЦикла;
- Возврат СтрокаХекс;
- КонецЕсли;
- Возврат Неопределено;
- КонецФункции
- Процедура УпаковатьДанные(МассивБайт, АдресСегмента, Секция, Данные)
- АдресСекции = АдресСегмента + Секция.Смещение;
- Если Найти(Секция.ИмяСекции, "Неизвестно") > 0 Тогда
- Возврат; // отладка
- КонецЕсли;
- Если Секция.ТипУпаковки="Число" Тогда
- Число = Мин(65535, Данные);
- МассивБайт[АдресСекции] = Данные % 256;
- МассивБайт[АдресСекции+1] = Цел(Данные / 256);
- ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
- МассивБайт[АдресСекции] = ?(Данные, 1, 0);
- ИначеЕсли Секция.ТипУпаковки="Строка" Тогда
- Строка = Лев(Данные, Секция.размер/2-1)+Символ(0);
- ДлинаСтроки = СтрДлина(Строка);
- Для й=0 по ДлинаСтроки-1 Цикл
- ч = КодСимвола(Строка, й+1);
- МассивБайт[АдресСекции+й*2] = ч % 256;
- МассивБайт[АдресСекции+й*2+1] = Цел(ч / 256);
- КонецЦикла;
- Иначе
- Строка = ВРЕГ(СокрЛП(Данные));
- Строка = СтрЗаменить(Строка, "-", " ");
- Строка = СтрЗаменить(Строка, " ", Символы.ПС);
- Для й=0 по Мин(Секция.Размер, СтрЧислоСтрок(Строка))-1 Цикл
- ХексСтрока = СтрПолучитьСтроку(Строка, й+1);
- Число = мХексЧисла[ХексСтрока];
- МассивБайт[АдресСекции+й] = Число;
- КонецЦикла;
- КонецЕсли;
- КонецПроцедуры
- Функция СформироватьФайлRPB() Экспорт
- КолЗаписей = ТаблицаДанных.Количество();
- КолСтраниц = Цел((КолЗаписей-1)/128)+1;
- МассивБайт = Новый Массив(25+КолСтраниц*128+КолЗаписей*6138);
- // вписываем неизменяемые данные (заголовок)
- ХексЗаголовок = "04 00 00 00-00 00 00 00-00 00 00 00-fa 17 00 00
- |80 00 00 00-01 00 00 00-01";
- СекцияЗаголовок = НоваяСекция(0, 25, "", "Заголовок");
- УпаковатьДанные(МассивБайт, 0, СекцияЗаголовок, ХексЗаголовок);
- // вписываем индексы страниц
- Для й=0 по КолСтраниц-1 Цикл
- СекцияИндексСтраницы = НоваяСекция(0, 128, "", "Индекс");
- АдресИндексаСтраницы = 25+й*(128+6138*128);
- ХексИндексСтраницы = Лев( СтрПовторить("01 ", КолЗаписей-й*128) + СтрПовторить("00 ", 128), 128 );
- УпаковатьДанные(МассивБайт, АдресИндексаСтраницы, СекцияИндексСтраницы, ХексИндексСтраницы);
- КонецЦикла;
- // для каждой записи (для каждого семента)
- Для й=0 По КолЗаписей-1 Цикл
- НомерСтраницы = Цел((й)/128)+1;
- АдресСегмента = 25+НомерСтраницы*128+й*6138;
- ТекСтр = ТаблицаДанных[й];
- // для каждой секции
- Для ц=0 По мСекции.Количество()-1 Цикл
- УпаковатьДанные(МассивБайт, АдресСегмента, мСекции[ц], ТекСтр[мСекции[ц].ИмяСекции]);
- КонецЦикла;
- КонецЦикла;
- ДвоичныеДанныеФайла = ЗаписатьМассивПолезныхБайтВФайлRPB(МассивБайт);
- Возврат ДвоичныеДанныеФайла;
- КонецФункции
- Функция СформироватьФайлCSV(Колонки="") Экспорт
- ТекстCSV = СформироватьТекстCSV(Колонки);
- ИмяВремФайла = ПолучитьИмяВременногоФайла(".csv");
- ФайлЗаписи = Новый ЗаписьТекста (ИмяВремФайла, КодировкаТекста.UTF8);
- ФайлЗаписи.Записать(ТекстCSV);
- ФайлЗаписи.Закрыть();
- ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВремФайла);
- УдалитьФайлы(ИмяВремФайла);
- Возврат ДвоичныеДанныеФайла;
- КонецФункции
- Функция СформироватьТекстCSV(Колонки="") Экспорт
- ТаблицаCSV = Новый ТаблицаЗначений;
- Если ЗначениеЗаполнено(Колонки) Тогда
- мКолонки = РазложитьСтрокуВМассивПодстрок(Колонки, ",");
- // выводим только указанные колонки
- Для й=0 по мКолонки.Количество()-1 Цикл
- Для ц=0 по мСекции.Количество()-1 Цикл
- Если мКолонки[й]=мСекции[ц].ИмяСекции Тогда
- ТаблицаCSV.Колонки.Добавить(мСекции[ц].ИмяСекции, Новый ОписаниеТипов("Строка"));
- КонецЕсли;
- КонецЦикла;
- КонецЦикла;
- Иначе
- // выведем известные колонки
- Для й=0 по мСекции.Количество()-1 Цикл
- Если Найти(мСекции[й].ИмяСекции, "Неизвестно")=0 Тогда
- ТаблицаCSV.Колонки.Добавить(мСекции[й].ИмяСекции, Новый ОписаниеТипов("Строка"));
- КонецЕсли;
- КонецЦикла;
- КонецЕсли;
- // приведем формат к Строке
- Для Каждого ТекСтрока из ТаблицаДанных Цикл
- НовСтрока = ТаблицаCSV.Добавить();
- Для й=0 по ТаблицаCSV.Колонки.Количество()-1 Цикл
- Секция = Секции[ТаблицаCSV.Колонки[й].Имя];
- Если Секция.ТипУпаковки="Число" Тогда
- НовСтрока[Секция.ИмяСекции] = Формат(ТекСтрока[Секция.ИмяСекции], "ЧГ=0");
- ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
- НовСтрока[Секция.ИмяСекции] = Формат(ТекСтрока[Секция.ИмяСекции], "БЛ=0; БИ=1");
- Иначе
- НовСтрока[Секция.ИмяСекции] = ТекСтрока[Секция.ИмяСекции];
- КонецЕсли;
- КонецЦикла;
- КонецЦикла;
- ТекстCSV = ПреобразоватьТЗвТекстCSV(ТаблицаCSV, ";", Истина);
- Возврат ТекстCSV;
- КонецФункции
- Функция СформироватьТаблицуДанных(Колонки="") Экспорт
- Таблица = Новый ТаблицаЗначений;
- Если ЗначениеЗаполнено(Колонки) Тогда
- мКолонки = РазложитьСтрокуВМассивПодстрок(Колонки, ",");
- // выводим только указанные колонки
- Для й=0 по мКолонки.Количество()-1 Цикл
- Для ц=0 по мСекции.Количество()-1 Цикл
- Если мКолонки[й]=мСекции[ц].ИмяСекции Тогда
- Таблица.Колонки.Добавить(мСекции[ц].ИмяСекции, Новый ОписаниеТипов(мСекции[ц].ТипУпаковки));
- КонецЕсли;
- КонецЦикла;
- КонецЦикла;
- Иначе
- // выведем известные колонки
- Для й=0 по мСекции.Количество()-1 Цикл
- Если Найти(мСекции[й].ИмяСекции, "Неизвестно")=0 Тогда
- Таблица.Колонки.Добавить(мСекции[й].ИмяСекции, Новый ОписаниеТипов(мСекции[й].ТипУпаковки));
- КонецЕсли;
- КонецЦикла;
- КонецЕсли;
- Для Каждого ТекСтр из ТаблицаДанных Цикл
- НовСтр = Таблица.Добавить();
- ЗаполнитьЗначенияСвойств(НовСтр, ТекСтр);
- КонецЦикла;
- Возврат Таблица;
- КонецФункции
- Процедура ЗагрузитьФайлRPB(ДвоичныеДанныеФайла) Экспорт
- // читаем файл
- МассивБайт = ПолучитьМассивПолезныхБайтИзФайлаRPB(ДвоичныеДанныеФайла);
- КоличествоБайт = МассивБайт.Количество();
- КоличествоСтраниц = Окр( (КоличествоБайт-25)/(6138*128+128)+0.5, 0, РежимОкругления.Окр15как10 );
- КоличествоЗаписей = ((КоличествоБайт-25)-128*КоличествоСтраниц)/6138;
- // для каждого семента (для каждой записи)
- Для й=0 По КоличествоЗаписей-1 Цикл
- НомерСтраницы = Цел((й)/128)+1;
- АдресСегмента = 25+НомерСтраницы*128+й*6138;
- НовСтр = ТаблицаДанных.Добавить();
- // для каждой секции
- Для ц=0 По мСекции.Количество()-1 Цикл
- НовСтр[мСекции[ц].ИмяСекции] = РаспаковатьДанные(МассивБайт, АдресСегмента, мСекции[ц]);
- КонецЦикла;
- //НовСтр["ХексДампСегмента"] = РаспаковатьДанные(МассивБайт, АдресСегмента, НоваяСекция(0, 6138+?( (й+1)%128=0,128,0))); // отладка
- КонецЦикла;
- КонецПроцедуры
- Процедура ЗагрузитьФайлCSV(ДвоичныеДанныеФайла) Экспорт
- // ДД -> ТекстФайла
- ИмяВремФайла = ПолучитьИмяВременногоФайла(".rpb");
- ДвоичныеДанныеФайла.Записать(ИмяВремФайла);
- ТекстовыйДокумент = Новый ТекстовыйДокумент;
- ТекстовыйДокумент.Прочитать(ИмяВремФайла);
- ТекстCSV = ТекстовыйДокумент.ПолучитьТекст();
- УдалитьФайлы(ИмяВремФайла);
- ЗагрузитьТекстCSV(ТекстCSV);
- КонецПроцедуры
- Процедура ЗагрузитьТекстCSV(ТекстCSV) Экспорт
- ТаблицаДанных.Очистить();
- ТаблицаCSV = ПреобразоватьТекстCSVвТЗ(ТекстCSV);
- Для Каждого ТекСтрока из ТаблицаCSV Цикл
- // пропустим строку заголовков
- Если ТаблицаCSV.Индекс(ТекСтрока) = 0 тогда
- Продолжить;
- КонецЕсли;
- НовСтрока = ТаблицаДанных.Добавить();
- Для й=0 по ТаблицаCSV.Колонки.Количество()-1 Цикл
- Секция = Секции[ТаблицаCSV[0][й]];
- // загрузим только известные колонки
- Если Секция <> Неопределено Тогда
- // приведем к формату число и булево
- Если Секция.ТипУпаковки="Число" Тогда
- Попытка
- НовСтрока[Секция.ИмяСекции] = Число("0"+СокрЛП(ТекСтрока[й]));
- Исключение
- Сообщить("Для записи "+(ТаблицаДанных.Индекс(НовСтрока)+1)+" в колонке "+Секция.ИмяСекции+" не удалось преобразовать """+ТекСтрока[й]+""" в число!");
- КонецПопытки;
- ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
- НовСтрока[Секция.ИмяСекции] = ?(СокрЛП(ТекСтрока[й])="1", Истина, Ложь);
- Иначе
- НовСтрока[Секция.ИмяСекции] = ТекСтрока[й];
- КонецЕсли;
- КонецЕсли;
- КонецЦикла;
- КонецЦикла;
- КонецПроцедуры
- Процедура ЗагрузитьТаблицуДанных(Таблица) Экспорт
- ТаблицаДанных.Очистить();
- Для Каждого ТекСтр из Таблица Цикл
- НовСтр = ТаблицаДанных.Добавить();
- ЗаполнитьЗначенияСвойств(НовСтр, ТекСтр);
- КонецЦикла;
- КонецПроцедуры
- Процедура ВывестиДеревоДанныхНаФорму(УФ, ИмяТаблицы) Экспорт
- КонецПроцедуры
- Процедура ВывестиТаблицуДанныхНаФорму(УФ, ИмяТаблицы) Экспорт
- ВывестиТаблицуНаФорму(УФ, ИмяТаблицы, ТаблицаДанных);
- //УФ.Элементы[ИмяТаблицы].КартинкаСтрок = Новый Картинка(); // низзя...
- УФ.Элементы[ИмяТаблицы].ПутьКДаннымКартинкиСтроки = ИмяТаблицы+".ЭтоГруппа";
- // проставим список выбора
- Для й=0 по мСекции.Количество()-1 Цикл
- Если ЗначениеЗаполнено(мСекции[й].Расшифровка) Тогда
- УФ.Элементы[ИмяТаблицы+мСекции[й].ИмяСекции].РежимВыбораИзСписка = Истина;
- Для ц=0 по мСекции[й].Расшифровка.Количество()-1 Цикл
- УФ.Элементы[ИмяТаблицы+мСекции[й].ИмяСекции].СписокВыбора.Добавить(ц, мСекции[й].Расшифровка[ц]);
- КонецЦикла;
- КонецЕсли;
- КонецЦикла;
- КонецПроцедуры
- Процедура ПреобразоватьТЗвДЗРекурсия(Таблица, Дерево, ИД=0)
- СтрокиДерева = Дерево.ПолучитьЭлементы();
- Отбор = Новый Структура;
- Отбор.Вставить("ИДРодителя", ИД);
- тМассив = Таблица.НайтиСтроки(Отбор);
- Для Каждого тСтр Из тМассив Цикл
- нСтр = СтрокиДерева.Добавить();
- ЗаполнитьЗначенияСвойств(нСтр, тСтр);
- Если тСтр["ИДЗаписи"] <> тСтр["ИДРодителя"] Тогда
- ПреобразоватьТЗвДЗРекурсия(Таблица, нСтр, тСтр["ИДЗаписи"]);
- КонецЕсли;
- //Элементы.дзАдреснаяКнига.Развернуть(нСтр.ПолучитьИдентификатор());
- КонецЦикла;
- КонецПроцедуры
- Процедура ПреобразоватьДЗвТЗРекурсия(Дерево, Таблица)
- Для Каждого тСтр Из Дерево.ПолучитьЭлементы() Цикл
- нСтр = Таблица.Добавить();
- ЗаполнитьЗначенияСвойств(нСтр, тСтр);
- ПреобразоватьДЗвТЗРекурсия(тСтр, Таблица);
- КонецЦикла;
- КонецПроцедуры
- ///////////////////////////////////////////////////////////
- // Инициализация структур данных
- ///////////////////////////////////////////////////////////
- // для быстрого преобразования HEX<->Число
- мХексСтроки = Новый Соответствие;
- мХексЧисла = Новый Соответствие;
- Для й=0 по 255 Цикл
- мХексЧисла.Вставить(Byte2Hex(й), й);
- мХексСтроки.Вставить(й, Byte2Hex(й));
- КонецЦикла;
- // так и не расшифрованные секции
- НеизвСекцияА = "01 00 00 00 " + СтрПовторить("00 ", 116);
- НеизвСекцияБ = "02 00 00 00 02 00 00 00 03 00 00 00 " + СтрПовторить("00 ", 2564);
- // фиксированная структура записи, заголовок - 25 байт, индекс страницы - 128 байт, сегмент - 6138 байт, страница - 128 сегментов
- // Смещение Размер ТипУпаковки ИмяСекции ЗначениеПоУмолчанию Расшифровка
- мСекции = Новый Массив;
- мСекции.Добавить(НоваяСекция(0, 4, "Число", "Частота", 100, ));
- мСекции.Добавить(НоваяСекция(4, 4, "Число", "ВидЭкрана", 0, "Обычный *, Полноэкранный, С масштабированием, Полноэкранный с масштабированием"));
- мСекции.Добавить(НоваяСекция(8, 4, "Число", "ГлубинаЦвета", 0, "16 бит *, 8 бит, 4 бита, 24 бита, 2 бита, 1 бит"));
- мСекции.Добавить(НоваяСекция(12, 4, "Число", "СпецСочетания", 0, "Нет, Да *"));
- мСекции.Добавить(НоваяСекция(16, 4, "Число", "Неизвестно1", 0, ));
- мСекции.Добавить(НоваяСекция(20, 4, "Число", "Неизвестно2", 0, ));
- мСекции.Добавить(НоваяСекция(24, 4, "Число", "Курсор", 0, "Не показывать, Удаленный *, Локальный и удаленный"));
- мСекции.Добавить(НоваяСекция(28, 120, , "Неизвестно3", НеизвСекцияА, ));
- мСекции.Добавить(НоваяСекция(148, 4, "Число", "КачествоЗвука", 0, "Уровень1, Уровень2, Уровень3, Уровень4, Уровень5, Уровень6 *"));
- мСекции.Добавить(НоваяСекция(152, 32*2, "Строка", "ГолосовойЧатИмя", "User", ));
- мСекции.Добавить(НоваяСекция(216, 512*2, "Строка", "ГолосовойЧатИнфо", "", ));
- мСекции.Добавить(НоваяСекция(1240, 32*2, "Строка", "ТекстовыйЧатИмя", "User", ));
- мСекции.Добавить(НоваяСекция(1304, 512*2, "Строка", "ТекстовыйЧатИнфо", "", ));
- мСекции.Добавить(НоваяСекция(2328, 2576, , "Неизвестно4", НеизвСекцияБ, ));
- мСекции.Добавить(НоваяСекция(4904, 100*2, "Строка", "Адрес", "127.0.0.1", ));
- мСекции.Добавить(НоваяСекция(5104, 100*2, "Строка", "ИмяЗаписи", "Тест", ));
- мСекции.Добавить(НоваяСекция(5304, 4, "Число", "Порт", 4899, ));
- мСекции.Добавить(НоваяСекция(5308, 200, "Строка", "Логин", "admin", ));
- мСекции.Добавить(НоваяСекция(5508, 200, "Строка", "Домен", "", ));
- мСекции.Добавить(НоваяСекция(5708, 200, "Строка", "ИмяХоста", "", ));
- мСекции.Добавить(НоваяСекция(5908, 200, "Строка", "Неизвестно5", "", ));
- мСекции.Добавить(НоваяСекция(6108, 4, "Число", "NoWinLogin", 0, "Нет *, Да"));
- мСекции.Добавить(НоваяСекция(6112, 4, "Число", "ИДЗаписи", 0, ));
- мСекции.Добавить(НоваяСекция(6116, 4, "Число", "ИДСервера", 0, ));
- мСекции.Добавить(НоваяСекция(6120, 4, "Число", "ИДРодителя", 0, ));
- мСекции.Добавить(НоваяСекция(6124, 2, "Булево", "ЭтоГруппа", Ложь, ));
- мСекции.Добавить(НоваяСекция(6126, 4, "Число", "Неизвестно6", 0, ));
- мСекции.Добавить(НоваяСекция(6130, 4, "Число", "Неизвестно7", 0, ));
- мСекции.Добавить(НоваяСекция(6134, 4, "Число", "Неизвестно8", 0, ));
- // заполним структуру сеций для обращения по имени
- Секции = Новый Структура;
- Для й=0 по мСекции.Количество()-1 Цикл
- Секции.Вставить(мСекции[й].ИмяСекции, мСекции[й]);
- КонецЦикла;
- // таблица значений для распаковки записей
- ТаблицаДанных = Новый ТаблицаЗначений;
- Для й=0 по мСекции.Количество()-1 Цикл
- ТекКолонка = ТаблицаДанных.Колонки.Добавить(мСекции[й].ИмяСекции, Новый ОписаниеТипов(мСекции[й].ТипУпаковки));//, мСекции[й].Синоним+" ["+СтрСоединить(мСекции[й].Расшифровка,",")+"]");
- // для удобства поставим поля в начало...
- Если мСекции[й].ИмяСекции = "ИмяЗаписи" Тогда
- ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 0-й);
- ИначеЕсли мСекции[й].ИмяСекции = "Адрес" Тогда
- ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 0-й);
- ИначеЕсли мСекции[й].ИмяСекции = "Порт" Тогда
- ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 2-й);
- ИначеЕсли мСекции[й].ИмяСекции = "ЭтоГруппа" Тогда
- ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 3-й);
- КонецЕсли;
- КонецЦикла;
Advertisement
Add Comment
Please, Sign In to add comment