kuzyara

Импорт/экспорт книги Radmin

Sep 5th, 2016
609
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 47.19 KB | None | 0 0
  1. Перем
  2. мСекции Экспорт,
  3. Секции,
  4. мХексЧисла,
  5. мХексСтроки,
  6. ТаблицаДанных;
  7.  
  8. #Область СлужебныеПроцерурыИФункции
  9.  
  10. Функция Byte2Hex(Знач Byte)
  11. Low = Byte % 16;
  12. High = (Byte - Low) / 16;
  13. Возврат Dec2Hex(High)+Dec2Hex(Low);
  14. КонецФункции
  15.  
  16. Функция Dec2Hex(Знач Значение)
  17. стрХекс = Из_Число_В_XСчисл(Значение, "0123456789ABCDEF");
  18. Возврат стрХекс;
  19. КонецФункции
  20.  
  21. Функция Hex2Dec(Знач Значение)
  22. стрХекс = Из_ХСчисл_В_Число(Значение, "0123456789ABCDEF");
  23. Возврат стрХекс;
  24. КонецФункции
  25.  
  26. // http://infostart.ru/public/70053/
  27. //
  28. Функция Из_Число_В_XСчисл(Знач Значение, Шаблон)
  29. Результат="";
  30. Основание = СтрДлина(Шаблон);
  31. Пока Значение>0 цикл
  32. Остат = Значение%Основание;
  33. Результат1=Сред(Шаблон,Остат+1,1);
  34. Значение = (Значение-Остат)/Основание;
  35. Результат = Результат1 + Результат;
  36. КонецЦикла;
  37. Возврат ?(ПустаяСтрока(Результат), Сред(Шаблон, 1, 1), Результат);
  38. КонецФункции
  39.  
  40. // http://infostart.ru/public/95428/
  41. //
  42. Функция Из_ХСчисл_В_Число(Знач аф,Шаблон)
  43. аф = ВРег(аф); // на всякий случай.
  44. ДлинаШаблона = СтрДлина(Шаблон);
  45.  
  46. ДлинаСтроки = СтрДлина(аф);
  47. Результат = 0;
  48.  
  49. Для ТекСимвол = 1 По ДлинаСтроки Цикл
  50. ОбрабатываемыйСимвол = Сред(аф, ТекСимвол,1);
  51. ПозицияВШаблоне = Найти(Шаблон,ОбрабатываемыйСимвол)-1;
  52. Результат = Результат * ДлинаШаблона + ПозицияВШаблоне;
  53. КонецЦикла;
  54.  
  55. Возврат(Результат);
  56.  
  57. КонецФункции
  58.  
  59. // https://helpf.pro/faq/view/351.html
  60. //
  61. Функция РазложитьСтрокуВМассивПодстрок(Знач Строка, Знач Разделитель = ",",
  62. Знач ПропускатьПустыеСтроки = Истина)
  63.  
  64. Результат = Новый Массив;
  65.  
  66. // для обеспечения обратной совместимости
  67. Если ПропускатьПустыеСтроки = Неопределено Тогда
  68. ПропускатьПустыеСтроки = ?(Разделитель = " ", Истина, Ложь);
  69. Если ПустаяСтрока(Строка) Тогда
  70. Если Разделитель = " " Тогда
  71. Результат.Добавить("");
  72. КонецЕсли;
  73. Возврат Результат;
  74. КонецЕсли;
  75. КонецЕсли;
  76. //
  77.  
  78. Позиция = Найти(Строка, Разделитель);
  79. Пока Позиция > 0 Цикл
  80. Подстрока = Лев(Строка, Позиция - 1);
  81. Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Подстрока) Тогда
  82. Результат.Добавить(Подстрока);
  83. КонецЕсли;
  84. Строка = Сред(Строка, Позиция + СтрДлина(Разделитель));
  85. Позиция = Найти(Строка, Разделитель);
  86. КонецЦикла;
  87.  
  88. Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Строка) Тогда
  89. Результат.Добавить(Строка);
  90. КонецЕсли;
  91.  
  92. Возврат Результат;
  93.  
  94. КонецФункции
  95.  
  96. Функция СтрПовторить(Знач Строка, КолРаз)
  97. рез="";
  98. Для й=1 по КолРаз Цикл
  99. рез = рез + Строка;
  100. КонецЦикла;
  101. Возврат Рез;
  102. КонецФункции
  103.  
  104. // http://forum.infostart.ru/forum24/topic88416/message932315/#message932315
  105. //
  106. Процедура ВывестиТаблицуНаФорму(УФ,ИмяТЗНаФорме,ТЗ, ТЗОбработчиковСобытий = Неопределено)
  107.  
  108. // СОЗДАНИЕ РЕКВИЗИТОВ ФОРМЫ
  109. МассивДобавляемыхРеквизитов = Новый Массив;
  110.  
  111. Для Каждого Колонка Из ТЗ.Колонки Цикл
  112. МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения,ИмяТЗНаФорме ,Колонка.Заголовок));
  113. КонецЦикла;
  114.  
  115. МассивУдаляемыхРеквизитов = УФ.ПолучитьРеквизиты(ИмяТЗНаФорме);
  116. МассивИменУдаляемыхРеквизитов = Новый Массив;
  117.  
  118. Для каждого Элемент Из МассивУдаляемыхРеквизитов Цикл
  119. МассивИменУдаляемыхРеквизитов.Добавить(ИмяТЗНаФорме + "." + Элемент.Имя);
  120. КонецЦикла;
  121.  
  122. УФ.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов,МассивИменУдаляемыхРеквизитов);
  123.  
  124. // СОЗДАНИЕ ЭЛЕМЕНТОВ ФОРМЫ
  125. Для каждого Элемент Из МассивУдаляемыхРеквизитов Цикл
  126. УдаляемыйЭлемент = УФ.Элементы.Найти(ИмяТЗНаФорме + Элемент.Имя);
  127. УФ.Элементы.Удалить(УдаляемыйЭлемент);
  128. КонецЦикла;
  129.  
  130. Для Каждого Колонка Из ТЗ.Колонки Цикл
  131. НоваяКолонка = УФ.Элементы.Добавить(ИмяТЗНаФорме + Колонка.Имя, Тип("ПолеФормы"), УФ.Элементы[ИмяТЗНаФорме]);
  132. НоваяКолонка.Заголовок = Колонка.Заголовок;
  133. НоваяКолонка.ПутьКДанным = ИмяТЗНаФорме + "." + Колонка.Имя;
  134. НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
  135. НоваяКолонка.РежимРедактирования = РежимРедактированияКолонки.ВходПриВводе;
  136. НоваяКолонка.МногострочныйРежим = Истина;
  137. НоваяКолонка.Высота = 1;
  138. НоваяКолонка.Видимость = НЕ Найти(Колонка.Имя, "Неизвестно"); // отладка
  139. КонецЦикла;
  140.  
  141. //УФ[ИмяТЗНаФорме].Очистить();
  142. //УФ[ИмяТЗНаФорме].Загрузить(ТЗ);
  143. УФ.ЗначениеВРеквизитФормы(ТЗ, ИмяТЗНаФорме);
  144.  
  145.  
  146. // Привязка обработчиков событий
  147. Если ТЗОбработчиковСобытий = Неопределено Тогда
  148. Возврат;
  149. КонецЕсли;
  150.  
  151. Для Каждого Строка Из ТЗОбработчиковСобытий Цикл
  152. УФ.Элементы[Строка.ИмяЭлемента].УстановитьДействие(Строка.ИмяСобытия, Строка.ИмяЭлемента + Строка.ИмяСобытия);
  153. КонецЦикла;
  154.  
  155. КонецПроцедуры
  156.  
  157. // http://infostart.ru/public/541555/
  158. //
  159. Функция ПреобразоватьТекстCSVвТЗ(ТекстCSV="", Разделитель=";") Экспорт
  160. ТЗ = Новый ТаблицаЗначений;
  161. ОсобаяСтрока = "$#%^&*!xyxb$#%&*!^"; // для замены ""
  162.  
  163. НомерСтроки = 1;
  164. Стр = СтрПолучитьСтроку(ТекстCSV,НомерСтроки);
  165. Пока НомерСтроки <= СтрЧислоСтрок(ТекстCSV) Цикл
  166. СтрокаТЗ = ТЗ.Добавить();
  167. НомерПоля = 0;
  168. Пока Стр <> "" Цикл
  169. Токен = "";
  170. ПозицияРазделителя = Найти(стр, Разделитель);
  171. ПозицияОткрКавычек = Найти(стр, """");
  172. Если (ПозицияРазделителя > ПозицияОткрКавычек ИЛИ ПозицияРазделителя = 0) И ПозицияОткрКавычек > 0 Тогда
  173. // начинающееся с кавычек читаем до тех пор
  174. Токен = Сред(Стр, 1, ПозицияОткрКавычек);
  175. Стр = СтрЗаменить(Сред(Стр, ПозицияОткрКавычек+1), """""", ОсобаяСтрока);
  176.  
  177. ПозицияЗакрКавычек = Найти(Стр, """");
  178. Пока ПозицияЗакрКавычек = 0 Цикл
  179. Токен = Токен + Стр + Символы.ПС;
  180. НомерСтроки = НомерСтроки + 1;
  181. Стр = СтрПолучитьСтроку(ТекстCSV, НомерСтроки);
  182. Стр = СтрЗаменить(Стр, """""", ОсобаяСтрока);
  183. // пока не встретим закрывающие
  184. ПозицияЗакрКавычек = Найти(Стр, """");
  185. КонецЦикла;
  186. ПозицияРазделителя=Найти(Сред(Стр,ПозицияЗакрКавычек), Разделитель);
  187. ПозицияРазделителя = ?(ПозицияРазделителя>0, ПозицияЗакрКавычек + ПозицияРазделителя-1, 0);
  188. КонецЕсли;
  189.  
  190. Токен = Токен + ?(ПозицияРазделителя>0, Сред(Стр, 1, ПозицияРазделителя-1), Стр);
  191. Стр = ?(ПозицияРазделителя>0, Сред(Стр, ПозицияРазделителя+1), "");
  192.  
  193. Если Лев(Токен, 1) = """" Тогда
  194. Токен = Сред(Токен, 2);
  195. Токен = ?(Прав(Токен, 1) = """", Сред(Токен, 1, СтрДлина(Токен)-1), Токен);
  196. КонецЕсли;
  197. Токен = СтрЗаменить(Токен, ОсобаяСтрока, """");
  198.  
  199. НомерПоля = НомерПоля + 1;
  200. Если ТЗ.Колонки.Количество()<НомерПоля Тогда
  201. ТЗ.Колонки.Добавить("Колонка"+НомерПоля, Новый ОписаниеТипов("Строка"));
  202. КонецЕсли;
  203. СтрокаТЗ[НомерПоля-1] = Токен;
  204.  
  205. КонецЦикла;
  206. НомерСтроки = НомерСтроки + 1;
  207. Стр = СтрПолучитьСтроку(ТекстCSV, НомерСтроки);
  208. КонецЦикла;
  209. Возврат ТЗ;
  210. КонецФункции
  211.  
  212. // http://infostart.ru/public/541555/
  213. //
  214. Функция ПреобразоватьТЗвТекстCSV(ТЗ, Разделитель = ";", флЭкспортироватьИменаКолонок = Ложь)
  215.  
  216. ТекстCSV = "";
  217.  
  218. Если флЭкспортироватьИменаКолонок Тогда
  219. //Если нужно выгружать наименование колонок Выгружаем
  220. ПодготовленнаяСтрока = "";
  221. Для Каждого Колонка Из ТЗ.Колонки Цикл
  222. ПодготовленнаяСтрока = ПодготовленнаяСтрока + Колонка.Имя + Разделитель;
  223. КонецЦикла;
  224. ПодготовленнаяСтрока = Лев (ПодготовленнаяСтрока,СтрДлина(ПодготовленнаяСтрока)-1);
  225.  
  226. ТекстCSV = ТекстCSV + ПодготовленнаяСтрока + Символы.ПС;
  227. КонецЕсли;
  228.  
  229. Для Каждого Строка Из ТЗ Цикл
  230. ПодготовленнаяСтрока = "";
  231. Для Каждого Колонка Из ТЗ.Колонки Цикл
  232. ПреобразованноеПоле = Строка[Колонка.Имя];
  233. //по правилам CSV если поле содержит двойные ковычки они должны повторятся дважды
  234. Если Найти(ПреобразованноеПоле,"""") Тогда
  235. ПреобразованноеПоле = СтрЗаменить(ПреобразованноеПоле,"""","""""");
  236. КонецЕсли;
  237. //по правилам CSV если поле содержит перенос строки или запятую оно должно заключатся в двойные кавычки
  238. Если Найти(ПреобразованноеПоле,Разделитель) ИЛИ Найти(ПреобразованноеПоле,Символы.ПС) ИЛИ Найти(ПреобразованноеПоле,"""") Тогда
  239. ПреобразованноеПоле = """" + ПреобразованноеПоле + """";
  240. КонецЕсли;
  241.  
  242. ПодготовленнаяСтрока = ПодготовленнаяСтрока + ПреобразованноеПоле + Разделитель;
  243. КонецЦикла;
  244. ПодготовленнаяСтрока = Лев (ПодготовленнаяСтрока,СтрДлина(ПодготовленнаяСтрока)-1);
  245.  
  246. ТекстCSV = ТекстCSV + ПодготовленнаяСтрока + Символы.ПС;
  247. КонецЦикла;
  248.  
  249. Возврат ТекстCSV;
  250. КонецФункции
  251.  
  252. #КонецОбласти
  253.  
  254. Функция НоваяСекция(Смещение, Размер, ТипУпаковки="", ИмяСекции="", ЗначениеПоУмолчанию=0, Расшифровка = "")
  255. Возврат Новый Структура("Смещение, ИмяСекции, Размер, ТипУпаковки, Расшифровка, ЗначениеПоУмолчанию", Смещение, ИмяСекции, Размер, ТипУпаковки, РазложитьСтрокуВМассивПодстрок(Расшифровка, ","), ЗначениеПоУмолчанию);
  256. КонецФункции
  257.  
  258. Функция ЗаписатьМассивПолезныхБайтВФайлRPB(МассивБайт)
  259. // магия
  260. КоличествоБайт = МассивБайт.Количество();
  261. КоличествоСтраниц = Окр( (КоличествоБайт-25)/(6138*128+128)+0.5, 0, РежимОкругления.Окр15как10 );
  262. КоличествоЗаписей = ((КоличествоБайт-25)-128*КоличествоСтраниц)/6138;
  263.  
  264. ТекстФайла = "";
  265.  
  266. // подготовим заготовки для секций типа "Строка" и ""
  267. Заготовки = Новый Структура;
  268. Для й=0 по мСекции.Количество()-1 Цикл
  269. Если мСекции[й].ТипУпаковки = "" Тогда
  270. Заготовка = "";
  271. Для Каждого ХексСтр из РазложитьСтрокуВМассивПодстрок(мСекции[й].ЗначениеПоУмолчанию, " ") Цикл
  272. ТекБайт = мХексЧисла[ХексСтр];
  273. Заготовка = Заготовка + Символ(ТекБайт);
  274. КонецЦикла;
  275. Заготовки.Вставить(мСекции[й].ИмяСекции, Заготовка);
  276.  
  277. ИначеЕсли мСекции[й].ТипУпаковки="Строка" Тогда
  278. Заготовка = СтрПовторить(Символ(0), мСекции[й].Размер);
  279. Заготовки.Вставить(мСекции[й].ИмяСекции, Заготовка);
  280.  
  281. КонецЕсли;
  282. КонецЦикла;
  283.  
  284. // запишем заголовок
  285. Для й=0 по 25-1 Цикл
  286. ТекстФайла = ТекстФайла + Символ(МассивБайт[й]);
  287. КонецЦикла;
  288.  
  289. // пишем только значащие данные
  290. Для й=0 По КоличествоЗаписей-1 Цикл
  291. НомерСтраницы = Цел((й)/128)+1;
  292. АдресСегмента = 25+НомерСтраницы*128+й*6138;
  293. СтрокаСегмента = "";
  294.  
  295. // для каждой секции
  296. Для ц=0 По мСекции.Количество()-1 Цикл
  297. Если мСекции[ц].ТипУпаковки = "" Тогда
  298. // НеизвСекцияА и НеизвСекцияБ возьмем из ЗначениеПоУмолчанию
  299. СтрокаСегмента = СтрокаСегмента + Заготовки[мСекции[ц].ИмяСекции];
  300. ИначеЕсли мСекции[ц].ТипУпаковки = "Строка" Тогда
  301. // строки уже оканчиваются null-байтом
  302. Для сч=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
  303. ТекБайт = МассивБайт[сч];
  304. Если ТекБайт <> Неопределено Тогда
  305. СтрокаСегмента = СтрокаСегмента + Символ(ТекБайт);
  306. Иначе
  307. Прервать;
  308. КонецЕсли;
  309. КонецЦикла;
  310. // поэтому дополняем нулями
  311. СтрокаСегмента = СтрокаСегмента + Сред(Заготовки[мСекции[ц].ИмяСекции], сч-(АдресСегмента+мСекции[ц].Смещение)+1);
  312. Иначе
  313. // остальные пишем полностью
  314. Для сч=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
  315. ТекБайт = МассивБайт[сч];
  316. СтрокаСегмента = СтрокаСегмента + Символ(?(ТекБайт=Неопределено, 0, ТекБайт));
  317. КонецЦикла;
  318. КонецЕсли;
  319. КонецЦикла;
  320.  
  321. ИндексСтраницы = ?(й%128=0, Лев( СтрПовторить(Символ(1), КоличествоЗаписей-й) + СтрПовторить(Символ(0), 128), 128 ), "");
  322.  
  323. ТекстФайла = ТекстФайла + ИндексСтраницы + СтрокаСегмента;
  324.  
  325. КонецЦикла;
  326.  
  327. // ТекстФайла -> ДД
  328. ИмяВремФайла = ПолучитьИмяВременногоФайла(".rpb");
  329. ТекстПостроитель = Новый ЗаписьXML;
  330. ТекстПостроитель.ОткрытьФайл(ИмяВремФайла,"ISO-8859-1");
  331. ТекстПостроитель.ЗаписатьБезОбработки(ТекстФайла); // #13#10 !
  332. ТекстПостроитель.Закрыть();
  333. ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВремФайла);
  334. УдалитьФайлы(ИмяВремФайла);
  335.  
  336. Возврат ДвоичныеДанныеФайла;
  337. КонецФункции
  338.  
  339. Функция ПолучитьМассивПолезныхБайтИзФайлаRPB(ДвоичныеДанныеФайла)
  340.  
  341. // ДД -> ТекстФайла
  342. ИмяВремФайла = ПолучитьИмяВременногоФайла(".rpb");
  343. ДвоичныеДанныеФайла.Записать(ИмяВремФайла);
  344. ТекстовыйДокумент = Новый ТекстовыйДокумент;
  345. ТекстовыйДокумент.Прочитать(ИмяВремФайла, "ISO-8859-1", "");
  346. ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
  347. УдалитьФайлы(ИмяВремФайла);
  348.  
  349. // магия
  350. МассивБайт = Новый Массив(СтрДлина(ТекстФайла));
  351. КоличествоБайт = МассивБайт.Количество();
  352. КоличествоСтраниц = Окр( (КоличествоБайт-25)/(6138*128+128)+0.5, 0, РежимОкругления.Окр15как10 );
  353. КоличествоЗаписей = ((КоличествоБайт-25)-128*КоличествоСтраниц)/6138;
  354.  
  355. NullСимвол = Символ(0);
  356.  
  357. // читаем только значащие данные
  358. Для й=0 по КоличествоЗаписей-1 Цикл
  359. НомерСтраницы = Цел((й)/128)+1;
  360. АдресСегмента = 25+НомерСтраницы*128+й*6138;
  361.  
  362. // для каждой секции
  363. Для ц=0 По мСекции.Количество()-1 Цикл
  364. Если мСекции[ц].ТипУпаковки = "" Тогда
  365. // НеизвСекцияА и НеизвСекцияБ пропускаем
  366. Продолжить;
  367. ИначеЕсли мСекции[ц].ТипУпаковки = "Строка" Тогда
  368. // строки считываем до null-term симола (2 нулевых байта)
  369. Для ы=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
  370. ТекСимвол = Сред(ТекстФайла, ы+1, 1);
  371. Если (ы+1)%2=0 И ТекСимвол = NullСимвол Тогда
  372. Прервать;
  373. Иначе
  374. МассивБайт[ы] = КодСимвола(ТекСимвол);
  375. КонецЕсли;
  376. КонецЦикла;
  377. Иначе
  378. // числа - считаем все 4 байта, булево - 2
  379. Для ы=АдресСегмента+мСекции[ц].Смещение По АдресСегмента+мСекции[ц].Смещение+мСекции[ц].Размер-1 Цикл
  380. ТекСимвол = Сред(ТекстФайла, ы+1, 1);
  381. МассивБайт[ы] = КодСимвола(ТекСимвол);
  382. КонецЦикла;
  383. КонецЕсли;
  384. КонецЦикла;
  385.  
  386. КонецЦикла;
  387.  
  388. Возврат МассивБайт;
  389. КонецФункции
  390.  
  391. Функция РаспаковатьДанные(МассивБайт, АдресСегмента, Секция)
  392. АдресСекции = АдресСегмента + Секция.Смещение;
  393. Если Найти(Секция.ИмяСекции, "Неизвестно") > 0 Тогда
  394. Возврат Неопределено; // отладка
  395. КонецЕсли;
  396.  
  397. Если Секция.ТипУпаковки="Число" Тогда
  398. Число = МассивБайт[АдресСекции+1]*256 + МассивБайт[АдресСекции]; // 16-bit unsigned integer WORD
  399. Возврат Число;
  400.  
  401. ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
  402. Флаг = МассивБайт[АдресСекции]=1;
  403. Возврат Флаг;
  404.  
  405. ИначеЕсли Секция.ТипУпаковки="Строка" Тогда
  406. Строка = "";
  407. Для й=0 по Секция.Размер/2-1 Цикл
  408. МладшийБайт = МассивБайт[АдресСекции+й*2];
  409. СтаршийБайт = МассивБайт[АдресСекции+й*2+1];
  410. Если МладшийБайт=Неопределено Тогда Прервать; КонецЕсли;
  411. КодСимвола = СтаршийБайт*256 + МладшийБайт; // 2-byte utf 8 char
  412. Если КодСимвола>0 Тогда
  413. Строка = Строка + Символ(КодСимвола);
  414. Иначе
  415. Прервать; // null terminated string
  416. КонецЕсли;
  417. КонецЦикла;
  418. Возврат Строка;
  419.  
  420. Иначе
  421. СтрокаХекс = "";
  422. Для й=0 по Секция.Размер-1 Цикл
  423. Байт = МассивБайт[АдресСекции+й];
  424. СтрокаХекс = СтрокаХекс + мХексСтроки[Байт] + ?((й+1)%16, " ", Символы.ПС);
  425. КонецЦикла;
  426. Возврат СтрокаХекс;
  427. КонецЕсли;
  428.  
  429. Возврат Неопределено;
  430.  
  431. КонецФункции
  432.  
  433. Процедура УпаковатьДанные(МассивБайт, АдресСегмента, Секция, Данные)
  434. АдресСекции = АдресСегмента + Секция.Смещение;
  435. Если Найти(Секция.ИмяСекции, "Неизвестно") > 0 Тогда
  436. Возврат; // отладка
  437. КонецЕсли;
  438.  
  439. Если Секция.ТипУпаковки="Число" Тогда
  440. Число = Мин(65535, Данные);
  441. МассивБайт[АдресСекции] = Данные % 256;
  442. МассивБайт[АдресСекции+1] = Цел(Данные / 256);
  443.  
  444. ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
  445. МассивБайт[АдресСекции] = ?(Данные, 1, 0);
  446.  
  447. ИначеЕсли Секция.ТипУпаковки="Строка" Тогда
  448. Строка = Лев(Данные, Секция.размер/2-1)+Символ(0);
  449. ДлинаСтроки = СтрДлина(Строка);
  450.  
  451. Для й=0 по ДлинаСтроки-1 Цикл
  452. ч = КодСимвола(Строка, й+1);
  453. МассивБайт[АдресСекции+й*2] = ч % 256;
  454. МассивБайт[АдресСекции+й*2+1] = Цел(ч / 256);
  455. КонецЦикла;
  456.  
  457. Иначе
  458. Строка = ВРЕГ(СокрЛП(Данные));
  459. Строка = СтрЗаменить(Строка, "-", " ");
  460. Строка = СтрЗаменить(Строка, " ", Символы.ПС);
  461. Для й=0 по Мин(Секция.Размер, СтрЧислоСтрок(Строка))-1 Цикл
  462. ХексСтрока = СтрПолучитьСтроку(Строка, й+1);
  463. Число = мХексЧисла[ХексСтрока];
  464. МассивБайт[АдресСекции+й] = Число;
  465. КонецЦикла;
  466.  
  467. КонецЕсли;
  468.  
  469. КонецПроцедуры
  470.  
  471. Функция СформироватьФайлRPB() Экспорт
  472.  
  473. КолЗаписей = ТаблицаДанных.Количество();
  474. КолСтраниц = Цел((КолЗаписей-1)/128)+1;
  475. МассивБайт = Новый Массив(25+КолСтраниц*128+КолЗаписей*6138);
  476.  
  477. // вписываем неизменяемые данные (заголовок)
  478. ХексЗаголовок = "04 00 00 00-00 00 00 00-00 00 00 00-fa 17 00 00
  479. |80 00 00 00-01 00 00 00-01";
  480.  
  481. СекцияЗаголовок = НоваяСекция(0, 25, "", "Заголовок");
  482. УпаковатьДанные(МассивБайт, 0, СекцияЗаголовок, ХексЗаголовок);
  483.  
  484. // вписываем индексы страниц
  485. Для й=0 по КолСтраниц-1 Цикл
  486. СекцияИндексСтраницы = НоваяСекция(0, 128, "", "Индекс");
  487. АдресИндексаСтраницы = 25+й*(128+6138*128);
  488. ХексИндексСтраницы = Лев( СтрПовторить("01 ", КолЗаписей-й*128) + СтрПовторить("00 ", 128), 128 );
  489. УпаковатьДанные(МассивБайт, АдресИндексаСтраницы, СекцияИндексСтраницы, ХексИндексСтраницы);
  490. КонецЦикла;
  491.  
  492.  
  493. // для каждой записи (для каждого семента)
  494. Для й=0 По КолЗаписей-1 Цикл
  495. НомерСтраницы = Цел((й)/128)+1;
  496. АдресСегмента = 25+НомерСтраницы*128+й*6138;
  497. ТекСтр = ТаблицаДанных[й];
  498.  
  499. // для каждой секции
  500. Для ц=0 По мСекции.Количество()-1 Цикл
  501. УпаковатьДанные(МассивБайт, АдресСегмента, мСекции[ц], ТекСтр[мСекции[ц].ИмяСекции]);
  502. КонецЦикла;
  503. КонецЦикла;
  504.  
  505. ДвоичныеДанныеФайла = ЗаписатьМассивПолезныхБайтВФайлRPB(МассивБайт);
  506. Возврат ДвоичныеДанныеФайла;
  507. КонецФункции
  508.  
  509. Функция СформироватьФайлCSV(Колонки="") Экспорт
  510. ТекстCSV = СформироватьТекстCSV(Колонки);
  511.  
  512. ИмяВремФайла = ПолучитьИмяВременногоФайла(".csv");
  513. ФайлЗаписи = Новый ЗаписьТекста (ИмяВремФайла, КодировкаТекста.UTF8);
  514. ФайлЗаписи.Записать(ТекстCSV);
  515. ФайлЗаписи.Закрыть();
  516. ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВремФайла);
  517. УдалитьФайлы(ИмяВремФайла);
  518. Возврат ДвоичныеДанныеФайла;
  519. КонецФункции
  520.  
  521. Функция СформироватьТекстCSV(Колонки="") Экспорт
  522. ТаблицаCSV = Новый ТаблицаЗначений;
  523.  
  524. Если ЗначениеЗаполнено(Колонки) Тогда
  525. мКолонки = РазложитьСтрокуВМассивПодстрок(Колонки, ",");
  526. // выводим только указанные колонки
  527. Для й=0 по мКолонки.Количество()-1 Цикл
  528. Для ц=0 по мСекции.Количество()-1 Цикл
  529. Если мКолонки[й]=мСекции[ц].ИмяСекции Тогда
  530. ТаблицаCSV.Колонки.Добавить(мСекции[ц].ИмяСекции, Новый ОписаниеТипов("Строка"));
  531. КонецЕсли;
  532. КонецЦикла;
  533. КонецЦикла;
  534. Иначе
  535. // выведем известные колонки
  536. Для й=0 по мСекции.Количество()-1 Цикл
  537. Если Найти(мСекции[й].ИмяСекции, "Неизвестно")=0 Тогда
  538. ТаблицаCSV.Колонки.Добавить(мСекции[й].ИмяСекции, Новый ОписаниеТипов("Строка"));
  539. КонецЕсли;
  540. КонецЦикла;
  541. КонецЕсли;
  542.  
  543. // приведем формат к Строке
  544. Для Каждого ТекСтрока из ТаблицаДанных Цикл
  545. НовСтрока = ТаблицаCSV.Добавить();
  546. Для й=0 по ТаблицаCSV.Колонки.Количество()-1 Цикл
  547. Секция = Секции[ТаблицаCSV.Колонки[й].Имя];
  548. Если Секция.ТипУпаковки="Число" Тогда
  549. НовСтрока[Секция.ИмяСекции] = Формат(ТекСтрока[Секция.ИмяСекции], "ЧГ=0");
  550. ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
  551. НовСтрока[Секция.ИмяСекции] = Формат(ТекСтрока[Секция.ИмяСекции], "БЛ=0; БИ=1");
  552. Иначе
  553. НовСтрока[Секция.ИмяСекции] = ТекСтрока[Секция.ИмяСекции];
  554. КонецЕсли;
  555. КонецЦикла;
  556. КонецЦикла;
  557.  
  558. ТекстCSV = ПреобразоватьТЗвТекстCSV(ТаблицаCSV, ";", Истина);
  559. Возврат ТекстCSV;
  560. КонецФункции
  561.  
  562. Функция СформироватьТаблицуДанных(Колонки="") Экспорт
  563. Таблица = Новый ТаблицаЗначений;
  564.  
  565. Если ЗначениеЗаполнено(Колонки) Тогда
  566. мКолонки = РазложитьСтрокуВМассивПодстрок(Колонки, ",");
  567. // выводим только указанные колонки
  568. Для й=0 по мКолонки.Количество()-1 Цикл
  569. Для ц=0 по мСекции.Количество()-1 Цикл
  570. Если мКолонки[й]=мСекции[ц].ИмяСекции Тогда
  571. Таблица.Колонки.Добавить(мСекции[ц].ИмяСекции, Новый ОписаниеТипов(мСекции[ц].ТипУпаковки));
  572. КонецЕсли;
  573. КонецЦикла;
  574. КонецЦикла;
  575. Иначе
  576. // выведем известные колонки
  577. Для й=0 по мСекции.Количество()-1 Цикл
  578. Если Найти(мСекции[й].ИмяСекции, "Неизвестно")=0 Тогда
  579. Таблица.Колонки.Добавить(мСекции[й].ИмяСекции, Новый ОписаниеТипов(мСекции[й].ТипУпаковки));
  580. КонецЕсли;
  581. КонецЦикла;
  582. КонецЕсли;
  583.  
  584. Для Каждого ТекСтр из ТаблицаДанных Цикл
  585. НовСтр = Таблица.Добавить();
  586. ЗаполнитьЗначенияСвойств(НовСтр, ТекСтр);
  587. КонецЦикла;
  588.  
  589. Возврат Таблица;
  590. КонецФункции
  591.  
  592. Процедура ЗагрузитьФайлRPB(ДвоичныеДанныеФайла) Экспорт
  593.  
  594. // читаем файл
  595. МассивБайт = ПолучитьМассивПолезныхБайтИзФайлаRPB(ДвоичныеДанныеФайла);
  596.  
  597. КоличествоБайт = МассивБайт.Количество();
  598. КоличествоСтраниц = Окр( (КоличествоБайт-25)/(6138*128+128)+0.5, 0, РежимОкругления.Окр15как10 );
  599. КоличествоЗаписей = ((КоличествоБайт-25)-128*КоличествоСтраниц)/6138;
  600.  
  601. // для каждого семента (для каждой записи)
  602. Для й=0 По КоличествоЗаписей-1 Цикл
  603. НомерСтраницы = Цел((й)/128)+1;
  604. АдресСегмента = 25+НомерСтраницы*128+й*6138;
  605. НовСтр = ТаблицаДанных.Добавить();
  606.  
  607. // для каждой секции
  608. Для ц=0 По мСекции.Количество()-1 Цикл
  609. НовСтр[мСекции[ц].ИмяСекции] = РаспаковатьДанные(МассивБайт, АдресСегмента, мСекции[ц]);
  610. КонецЦикла;
  611. //НовСтр["ХексДампСегмента"] = РаспаковатьДанные(МассивБайт, АдресСегмента, НоваяСекция(0, 6138+?( (й+1)%128=0,128,0))); // отладка
  612.  
  613. КонецЦикла;
  614.  
  615. КонецПроцедуры
  616.  
  617. Процедура ЗагрузитьФайлCSV(ДвоичныеДанныеФайла) Экспорт
  618.  
  619. // ДД -> ТекстФайла
  620. ИмяВремФайла = ПолучитьИмяВременногоФайла(".rpb");
  621. ДвоичныеДанныеФайла.Записать(ИмяВремФайла);
  622. ТекстовыйДокумент = Новый ТекстовыйДокумент;
  623. ТекстовыйДокумент.Прочитать(ИмяВремФайла);
  624. ТекстCSV = ТекстовыйДокумент.ПолучитьТекст();
  625. УдалитьФайлы(ИмяВремФайла);
  626.  
  627. ЗагрузитьТекстCSV(ТекстCSV);
  628.  
  629. КонецПроцедуры
  630.  
  631. Процедура ЗагрузитьТекстCSV(ТекстCSV) Экспорт
  632. ТаблицаДанных.Очистить();
  633.  
  634. ТаблицаCSV = ПреобразоватьТекстCSVвТЗ(ТекстCSV);
  635.  
  636. Для Каждого ТекСтрока из ТаблицаCSV Цикл
  637. // пропустим строку заголовков
  638. Если ТаблицаCSV.Индекс(ТекСтрока) = 0 тогда
  639. Продолжить;
  640. КонецЕсли;
  641.  
  642. НовСтрока = ТаблицаДанных.Добавить();
  643.  
  644. Для й=0 по ТаблицаCSV.Колонки.Количество()-1 Цикл
  645. Секция = Секции[ТаблицаCSV[0][й]];
  646. // загрузим только известные колонки
  647. Если Секция <> Неопределено Тогда
  648.  
  649. // приведем к формату число и булево
  650. Если Секция.ТипУпаковки="Число" Тогда
  651. Попытка
  652. НовСтрока[Секция.ИмяСекции] = Число("0"+СокрЛП(ТекСтрока[й]));
  653. Исключение
  654. Сообщить("Для записи "+(ТаблицаДанных.Индекс(НовСтрока)+1)+" в колонке "+Секция.ИмяСекции+" не удалось преобразовать """+ТекСтрока[й]+""" в число!");
  655. КонецПопытки;
  656. ИначеЕсли Секция.ТипУпаковки="Булево" Тогда
  657. НовСтрока[Секция.ИмяСекции] = ?(СокрЛП(ТекСтрока[й])="1", Истина, Ложь);
  658. Иначе
  659. НовСтрока[Секция.ИмяСекции] = ТекСтрока[й];
  660. КонецЕсли;
  661. КонецЕсли;
  662. КонецЦикла;
  663.  
  664. КонецЦикла;
  665.  
  666. КонецПроцедуры
  667.  
  668. Процедура ЗагрузитьТаблицуДанных(Таблица) Экспорт
  669. ТаблицаДанных.Очистить();
  670. Для Каждого ТекСтр из Таблица Цикл
  671. НовСтр = ТаблицаДанных.Добавить();
  672. ЗаполнитьЗначенияСвойств(НовСтр, ТекСтр);
  673. КонецЦикла;
  674. КонецПроцедуры
  675.  
  676. Процедура ВывестиДеревоДанныхНаФорму(УФ, ИмяТаблицы) Экспорт
  677.  
  678. КонецПроцедуры
  679.  
  680. Процедура ВывестиТаблицуДанныхНаФорму(УФ, ИмяТаблицы) Экспорт
  681.  
  682. ВывестиТаблицуНаФорму(УФ, ИмяТаблицы, ТаблицаДанных);
  683.  
  684. //УФ.Элементы[ИмяТаблицы].КартинкаСтрок = Новый Картинка(); // низзя...
  685. УФ.Элементы[ИмяТаблицы].ПутьКДаннымКартинкиСтроки = ИмяТаблицы+".ЭтоГруппа";
  686.  
  687. // проставим список выбора
  688. Для й=0 по мСекции.Количество()-1 Цикл
  689. Если ЗначениеЗаполнено(мСекции[й].Расшифровка) Тогда
  690. УФ.Элементы[ИмяТаблицы+мСекции[й].ИмяСекции].РежимВыбораИзСписка = Истина;
  691. Для ц=0 по мСекции[й].Расшифровка.Количество()-1 Цикл
  692. УФ.Элементы[ИмяТаблицы+мСекции[й].ИмяСекции].СписокВыбора.Добавить(ц, мСекции[й].Расшифровка[ц]);
  693. КонецЦикла;
  694. КонецЕсли;
  695. КонецЦикла;
  696.  
  697. КонецПроцедуры
  698.  
  699. Процедура ПреобразоватьТЗвДЗРекурсия(Таблица, Дерево, ИД=0)
  700. СтрокиДерева = Дерево.ПолучитьЭлементы();
  701. Отбор = Новый Структура;
  702. Отбор.Вставить("ИДРодителя", ИД);
  703. тМассив = Таблица.НайтиСтроки(Отбор);
  704. Для Каждого тСтр Из тМассив Цикл
  705. нСтр = СтрокиДерева.Добавить();
  706. ЗаполнитьЗначенияСвойств(нСтр, тСтр);
  707. Если тСтр["ИДЗаписи"] <> тСтр["ИДРодителя"] Тогда
  708. ПреобразоватьТЗвДЗРекурсия(Таблица, нСтр, тСтр["ИДЗаписи"]);
  709. КонецЕсли;
  710. //Элементы.дзАдреснаяКнига.Развернуть(нСтр.ПолучитьИдентификатор());
  711. КонецЦикла;
  712. КонецПроцедуры
  713.  
  714. Процедура ПреобразоватьДЗвТЗРекурсия(Дерево, Таблица)
  715. Для Каждого тСтр Из Дерево.ПолучитьЭлементы() Цикл
  716. нСтр = Таблица.Добавить();
  717. ЗаполнитьЗначенияСвойств(нСтр, тСтр);
  718. ПреобразоватьДЗвТЗРекурсия(тСтр, Таблица);
  719. КонецЦикла;
  720. КонецПроцедуры
  721.  
  722.  
  723. ///////////////////////////////////////////////////////////
  724. // Инициализация структур данных
  725. ///////////////////////////////////////////////////////////
  726.  
  727. // для быстрого преобразования HEX<->Число
  728. мХексСтроки = Новый Соответствие;
  729. мХексЧисла = Новый Соответствие;
  730. Для й=0 по 255 Цикл
  731. мХексЧисла.Вставить(Byte2Hex(й), й);
  732. мХексСтроки.Вставить(й, Byte2Hex(й));
  733. КонецЦикла;
  734.  
  735. // так и не расшифрованные секции
  736. НеизвСекцияА = "01 00 00 00 " + СтрПовторить("00 ", 116);
  737. НеизвСекцияБ = "02 00 00 00 02 00 00 00 03 00 00 00 " + СтрПовторить("00 ", 2564);
  738.  
  739. // фиксированная структура записи, заголовок - 25 байт, индекс страницы - 128 байт, сегмент - 6138 байт, страница - 128 сегментов
  740. // Смещение Размер ТипУпаковки ИмяСекции ЗначениеПоУмолчанию Расшифровка
  741. мСекции = Новый Массив;
  742. мСекции.Добавить(НоваяСекция(0, 4, "Число", "Частота", 100, ));
  743. мСекции.Добавить(НоваяСекция(4, 4, "Число", "ВидЭкрана", 0, "Обычный *, Полноэкранный, С масштабированием, Полноэкранный с масштабированием"));
  744. мСекции.Добавить(НоваяСекция(8, 4, "Число", "ГлубинаЦвета", 0, "16 бит *, 8 бит, 4 бита, 24 бита, 2 бита, 1 бит"));
  745. мСекции.Добавить(НоваяСекция(12, 4, "Число", "СпецСочетания", 0, "Нет, Да *"));
  746. мСекции.Добавить(НоваяСекция(16, 4, "Число", "Неизвестно1", 0, ));
  747. мСекции.Добавить(НоваяСекция(20, 4, "Число", "Неизвестно2", 0, ));
  748. мСекции.Добавить(НоваяСекция(24, 4, "Число", "Курсор", 0, "Не показывать, Удаленный *, Локальный и удаленный"));
  749. мСекции.Добавить(НоваяСекция(28, 120, , "Неизвестно3", НеизвСекцияА, ));
  750. мСекции.Добавить(НоваяСекция(148, 4, "Число", "КачествоЗвука", 0, "Уровень1, Уровень2, Уровень3, Уровень4, Уровень5, Уровень6 *"));
  751. мСекции.Добавить(НоваяСекция(152, 32*2, "Строка", "ГолосовойЧатИмя", "User", ));
  752. мСекции.Добавить(НоваяСекция(216, 512*2, "Строка", "ГолосовойЧатИнфо", "", ));
  753. мСекции.Добавить(НоваяСекция(1240, 32*2, "Строка", "ТекстовыйЧатИмя", "User", ));
  754. мСекции.Добавить(НоваяСекция(1304, 512*2, "Строка", "ТекстовыйЧатИнфо", "", ));
  755. мСекции.Добавить(НоваяСекция(2328, 2576, , "Неизвестно4", НеизвСекцияБ, ));
  756. мСекции.Добавить(НоваяСекция(4904, 100*2, "Строка", "Адрес", "127.0.0.1", ));
  757. мСекции.Добавить(НоваяСекция(5104, 100*2, "Строка", "ИмяЗаписи", "Тест", ));
  758. мСекции.Добавить(НоваяСекция(5304, 4, "Число", "Порт", 4899, ));
  759. мСекции.Добавить(НоваяСекция(5308, 200, "Строка", "Логин", "admin", ));
  760. мСекции.Добавить(НоваяСекция(5508, 200, "Строка", "Домен", "", ));
  761. мСекции.Добавить(НоваяСекция(5708, 200, "Строка", "ИмяХоста", "", ));
  762. мСекции.Добавить(НоваяСекция(5908, 200, "Строка", "Неизвестно5", "", ));
  763. мСекции.Добавить(НоваяСекция(6108, 4, "Число", "NoWinLogin", 0, "Нет *, Да"));
  764. мСекции.Добавить(НоваяСекция(6112, 4, "Число", "ИДЗаписи", 0, ));
  765. мСекции.Добавить(НоваяСекция(6116, 4, "Число", "ИДСервера", 0, ));
  766. мСекции.Добавить(НоваяСекция(6120, 4, "Число", "ИДРодителя", 0, ));
  767. мСекции.Добавить(НоваяСекция(6124, 2, "Булево", "ЭтоГруппа", Ложь, ));
  768. мСекции.Добавить(НоваяСекция(6126, 4, "Число", "Неизвестно6", 0, ));
  769. мСекции.Добавить(НоваяСекция(6130, 4, "Число", "Неизвестно7", 0, ));
  770. мСекции.Добавить(НоваяСекция(6134, 4, "Число", "Неизвестно8", 0, ));
  771.  
  772. // заполним структуру сеций для обращения по имени
  773. Секции = Новый Структура;
  774. Для й=0 по мСекции.Количество()-1 Цикл
  775. Секции.Вставить(мСекции[й].ИмяСекции, мСекции[й]);
  776. КонецЦикла;
  777.  
  778. // таблица значений для распаковки записей
  779. ТаблицаДанных = Новый ТаблицаЗначений;
  780. Для й=0 по мСекции.Количество()-1 Цикл
  781. ТекКолонка = ТаблицаДанных.Колонки.Добавить(мСекции[й].ИмяСекции, Новый ОписаниеТипов(мСекции[й].ТипУпаковки));//, мСекции[й].Синоним+" ["+СтрСоединить(мСекции[й].Расшифровка,",")+"]");
  782. // для удобства поставим поля в начало...
  783. Если мСекции[й].ИмяСекции = "ИмяЗаписи" Тогда
  784. ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 0-й);
  785. ИначеЕсли мСекции[й].ИмяСекции = "Адрес" Тогда
  786. ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 0-й);
  787. ИначеЕсли мСекции[й].ИмяСекции = "Порт" Тогда
  788. ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 2-й);
  789. ИначеЕсли мСекции[й].ИмяСекции = "ЭтоГруппа" Тогда
  790. ТаблицаДанных.Колонки.Сдвинуть(ТекКолонка, 3-й);
  791. КонецЕсли;
  792. КонецЦикла;
Advertisement
Add Comment
Please, Sign In to add comment