kuzyara

ПреобразоватьCSVвТЗ.epf

Sep 5th, 2016
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.76 KB | None | 0 0
  1. #Область ВспомогательныеФункций
  2.  
  3. // http://forum.infostart.ru/forum24/topic88416/message932315/#message932315
  4. //
  5. &НаСервере
  6. Процедура ВывестиТаблицуНаФорму(УФ,ИмяТЗНаФорме,ТЗ, ТЗОбработчиковСобытий = Неопределено) Экспорт
  7.  
  8. // СОЗДАНИЕ РЕКВИЗИТОВ ФОРМЫ
  9. МассивДобавляемыхРеквизитов = Новый Массив;
  10.  
  11. Для Каждого Колонка Из ТЗ.Колонки Цикл
  12. МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения,ИмяТЗНаФорме ,Колонка.Заголовок));
  13. КонецЦикла;
  14.  
  15. МассивУдаляемыхРеквизитов = УФ.ПолучитьРеквизиты(ИмяТЗНаФорме);
  16. МассивИменУдаляемыхРеквизитов = Новый Массив;
  17.  
  18. Для каждого Элемент Из МассивУдаляемыхРеквизитов Цикл
  19. МассивИменУдаляемыхРеквизитов.Добавить(ИмяТЗНаФорме + "." + Элемент.Имя);
  20. КонецЦикла;
  21.  
  22. УФ.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов,МассивИменУдаляемыхРеквизитов);
  23.  
  24. // СОЗДАНИЕ ЭЛЕМЕНТОВ ФОРМЫ
  25. Для каждого Элемент Из МассивУдаляемыхРеквизитов Цикл
  26. УдаляемыйЭлемент = УФ.Элементы.Найти(ИмяТЗНаФорме + Элемент.Имя);
  27. УФ.Элементы.Удалить(УдаляемыйЭлемент);
  28. КонецЦикла;
  29.  
  30. Для Каждого Колонка Из ТЗ.Колонки Цикл
  31. НоваяКолонка = УФ.Элементы.Добавить(ИмяТЗНаФорме + Колонка.Имя, Тип("ПолеФормы"), УФ.Элементы[ИмяТЗНаФорме]);
  32. НоваяКолонка.Заголовок = Колонка.Заголовок;
  33. НоваяКолонка.ПутьКДанным = ИмяТЗНаФорме + "." + Колонка.Имя;
  34. НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
  35. НоваяКолонка.РежимРедактирования = РежимРедактированияКолонки.ВходПриВводе;
  36. НоваяКолонка.МногострочныйРежим = Истина;
  37. НоваяКолонка.Высота = 1;
  38. КонецЦикла;
  39.  
  40. //УФ[ИмяТЗНаФорме].Очистить();
  41. //УФ[ИмяТЗНаФорме].Загрузить(ТЗ);
  42. ЗначениеВРеквизитФормы(ТЗ, ИмяТЗНаФорме);
  43.  
  44.  
  45. // Привязка обработчиков событий
  46. Если ТЗОбработчиковСобытий = Неопределено Тогда
  47. Возврат;
  48. КонецЕсли;
  49.  
  50. Для Каждого Строка Из ТЗОбработчиковСобытий Цикл
  51. УФ.Элементы[Строка.ИмяЭлемента].УстановитьДействие(Строка.ИмяСобытия, Строка.ИмяЭлемента + Строка.ИмяСобытия);
  52. КонецЦикла;
  53.  
  54. КонецПроцедуры
  55.  
  56. //ПреобразоватьТекстCSVвТЗ () импортирует данные в ТЗ из текста в формате CSV
  57. //Параметры:
  58. //ТекстCSV - Строка, содержащая текст в формате csv
  59. //Разделитель - Для формата CSV разделителем является ',', но т.к.
  60. // Excel берет разделитель из региональных стандартов, то
  61. // используется ';'
  62. //
  63. &НаСервереБезКонтекста
  64. Функция ПреобразоватьТекстCSVвТЗ(ТекстCSV="", Разделитель=";") Экспорт
  65. ТЗ = Новый ТаблицаЗначений;
  66. ОсобаяСтрока = "$#%^&*!xyxb$#%&*!^"; // для замены ""
  67.  
  68. НомерСтроки = 1;
  69. Стр = СтрПолучитьСтроку(ТекстCSV,НомерСтроки);
  70. Пока НомерСтроки <= СтрЧислоСтрок(ТекстCSV) Цикл
  71. СтрокаТЗ = ТЗ.Добавить();
  72. НомерПоля = 0;
  73. Пока Стр <> "" Цикл
  74. Токен = "";
  75. ПозицияРазделителя = Найти(стр, Разделитель);
  76. ПозицияОткрКавычек = Найти(стр, """");
  77. Если (ПозицияРазделителя > ПозицияОткрКавычек ИЛИ ПозицияРазделителя = 0) И ПозицияОткрКавычек > 0 Тогда
  78. // начинающееся с кавычек читаем до тех пор
  79. Токен = Сред(Стр, 1, ПозицияОткрКавычек);
  80. Стр = СтрЗаменить(Сред(Стр, ПозицияОткрКавычек+1), """""", ОсобаяСтрока);
  81.  
  82. ПозицияЗакрКавычек = Найти(Стр, """");
  83. Пока ПозицияЗакрКавычек = 0 Цикл
  84. Токен = Токен + Стр + Символы.ПС;
  85. НомерСтроки = НомерСтроки + 1;
  86. Стр = СтрПолучитьСтроку(ТекстCSV, НомерСтроки);
  87. Стр = СтрЗаменить(Стр, """""", ОсобаяСтрока);
  88. // пока не встретим закрывающие
  89. ПозицияЗакрКавычек = Найти(Стр, """");
  90. КонецЦикла;
  91. ПозицияРазделителя=Найти(Сред(Стр,ПозицияЗакрКавычек), Разделитель);
  92. ПозицияРазделителя = ?(ПозицияРазделителя>0, ПозицияЗакрКавычек + ПозицияРазделителя-1, 0);
  93. КонецЕсли;
  94.  
  95. Токен = Токен + ?(ПозицияРазделителя>0, Сред(Стр, 1, ПозицияРазделителя-1), Стр);
  96. Стр = ?(ПозицияРазделителя>0, Сред(Стр, ПозицияРазделителя+1), "");
  97.  
  98. Если Лев(Токен, 1) = """" Тогда
  99. Токен = Сред(Токен, 2);
  100. Токен = ?(Прав(Токен, 1) = """", Сред(Токен, 1, СтрДлина(Токен)-1), Токен);
  101. КонецЕсли;
  102. Токен = СтрЗаменить(Токен, ОсобаяСтрока, """");
  103.  
  104. НомерПоля = НомерПоля + 1;
  105. Если ТЗ.Колонки.Количество()<НомерПоля Тогда
  106. ТЗ.Колонки.Добавить("Колонка"+НомерПоля, Новый ОписаниеТипов("Строка"));
  107. КонецЕсли;
  108. СтрокаТЗ[НомерПоля-1] = Токен;
  109.  
  110. КонецЦикла;
  111. НомерСтроки = НомерСтроки + 1;
  112. Стр = СтрПолучитьСтроку(ТекстCSV, НомерСтроки);
  113. КонецЦикла;
  114. Возврат ТЗ;
  115. КонецФункции
  116.  
  117. //ПреобразоватьТЗвТекстCSV () экспортирует данные ТЗ в текст в формате CSV
  118. //Параметры:
  119. //ТЗ - Таблица значений данные которые сохраняются в файл
  120. //флЭкспортироватьИменаКолонок - Первой строкой выводить имена колонок
  121. //Разделитель - Для формата CSV разделителем является ',', но т.к.
  122. // Excel берет разделитель из региональных стандартов, то
  123. // используется ';'
  124. //
  125. &НаСервереБезКонтекста
  126. Функция ПреобразоватьТЗвТекстCSV(ТЗ, Разделитель = ";", флЭкспортироватьИменаКолонок = Ложь) Экспорт
  127.  
  128. ТекстCSV = "";
  129.  
  130. Если флЭкспортироватьИменаКолонок Тогда
  131. //Если нужно выгружать наименование колонок Выгружаем
  132. ПодготовленнаяСтрока = "";
  133. Для Каждого Колонка Из ТЗ.Колонки Цикл
  134. ПодготовленнаяСтрока = ПодготовленнаяСтрока + Колонка.Имя + Разделитель;
  135. КонецЦикла;
  136. ПодготовленнаяСтрока = Лев (ПодготовленнаяСтрока,СтрДлина(ПодготовленнаяСтрока)-1);
  137.  
  138. ТекстCSV = ТекстCSV + ПодготовленнаяСтрока + Символы.ПС;
  139. КонецЕсли;
  140.  
  141. Для Каждого Строка Из ТЗ Цикл
  142. ПодготовленнаяСтрока = "";
  143. Для Каждого Колонка Из ТЗ.Колонки Цикл
  144. ПреобразованноеПоле = Строка[Колонка.Имя];
  145. //по правилам CSV если поле содержит двойные ковычки они должны повторятся дважды
  146. Если Найти(ПреобразованноеПоле,"""") Тогда
  147. ПреобразованноеПоле = СтрЗаменить(ПреобразованноеПоле,"""","""""");
  148. КонецЕсли;
  149. //по правилам CSV если поле содержит перенос строки или запятую оно должно заключатся в двойные кавычки
  150. Если Найти(ПреобразованноеПоле,Разделитель) ИЛИ Найти(ПреобразованноеПоле,Символы.ПС) ИЛИ Найти(ПреобразованноеПоле,"""") Тогда
  151. ПреобразованноеПоле = """" + ПреобразованноеПоле + """";
  152. КонецЕсли;
  153.  
  154. ПодготовленнаяСтрока = ПодготовленнаяСтрока + ПреобразованноеПоле + Разделитель;
  155. КонецЦикла;
  156. ПодготовленнаяСтрока = Лев (ПодготовленнаяСтрока,СтрДлина(ПодготовленнаяСтрока)-1);
  157.  
  158. ТекстCSV = ТекстCSV + ПодготовленнаяСтрока + Символы.ПС;
  159. КонецЦикла;
  160.  
  161. Возврат ТекстCSV;
  162. КонецФункции
  163.  
  164. // Функция возвращает ТабличныйДокумент с данными файла.
  165. //
  166. &НаКлиенте
  167. Функция ПрочитатьCSV_ADO(ИмяФайла, Разделитель=",")
  168. ТабДок = Новый ТабличныйДокумент;
  169. Файл = Новый Файл(ИмяФайла);
  170.  
  171. Connection=Новый COMОбъект("ADODB.Connection");
  172. Connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Файл.Путь+";Extended Properties=""text;HDR=No;IMEX=1;FMT=Delimited""");
  173.  
  174. RecordSet=Новый COMОбъект("ADODB.Recordset");
  175. RecordSet.ActiveConnection = Connection;
  176.  
  177. RecordSet.Open("select * from "+Файл.Имя, Connection);
  178.  
  179. сч=0;
  180. Пока НЕ RecordSet.EOF() Цикл
  181. сч=сч+1;
  182.  
  183. Для й=0 по RecordSet.Fields.Count-1 Цикл
  184. ТабДок.Область(сч, й+1).Текст = RecordSet.Fields(й).Value;
  185. КонецЦикла;
  186. Если сч%1000=0 Тогда // ~ 1000 в секунду
  187. Состояние(""+сч+" ...");
  188. ОбработкаПрерыванияПользователя();
  189. КонецЕсли;
  190. RecordSet.MoveNext();
  191. КонецЦикла;
  192.  
  193. RecordSet.Close();
  194. Connection.Close();
  195. Возврат ТабДок;
  196. КонецФункции
  197.  
  198. // Функция возвращает ТаблицуЗначений с данными файла.
  199. //
  200. // Источник: http://forum.script-coding.com/viewtopic.php?id=5664
  201. //
  202. &НаСервере
  203. Функция ПрочитатьCSV_GWF(ИмяФайла)
  204. Файл = Новый Файл(ИмяФайла);
  205.  
  206. // Schema.ini уже должен быть подготовлен
  207. objRec = Новый COMОбъект("ADODB.Recordset");
  208. strQuery = "SELECT * FROM [" + Файл.Имя + "]";
  209. strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Файл.Путь + ";Extended Properties=""text;HDR=No""";
  210. adOpenStatic = 3;
  211. adLockOptimistic = 3;
  212. adCmdText = 1;
  213. objRec.Open(strQuery, strConn, adOpenStatic, adLockOptimistic, adCmdText);
  214.  
  215. Если ПодключитьВнешнююКомпоненту("GameWithFire.ADOUtils") Тогда
  216. ADOUtils = Новый("AddIn.ADOUtils");
  217. Возврат ADOUtils.ADORecordsetToValueTable(objRec); // ~ 3000 в сек
  218. Иначе
  219. Сообщить("Не удалось подключить компоненту GameWithFire");
  220. Возврат Новый ТаблицаЗначений;
  221. КонецЕсли;
  222. КонецФункции
  223.  
  224. &НаКлиенте
  225. Процедура ПрочитатьФайл(ИмяФайла, ТекстФайла)
  226. ЧтениеТекста = Новый ЧтениеТекста(ИмяФайла);
  227. ТекстФайла = ЧтениеТекста.Прочитать();
  228. ЧтениеТекста.Закрыть();
  229. КонецПроцедуры
  230.  
  231. &НаКлиенте
  232. Процедура ЗаписатьФайл(ИмяФайла, ТекстФайла)
  233. ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI);
  234. ЗаписьТекста.Записать(ТекстФайла);
  235. ЗаписьТекста.Закрыть();
  236. КонецПроцедуры
  237.  
  238. #КонецОбласти
  239.  
  240. &НаСервере
  241. Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
  242. // тесты
  243. Тесты = "";
  244. Тесты = Тесты + Символы.ПС + "a";
  245. Тесты = Тесты + Символы.ПС + "a;b;c";
  246. Тесты = Тесты + Символы.ПС + "a;b\nc";
  247. Тесты = Тесты + Символы.ПС + """a;b"";c";
  248. Тесты = Тесты + Символы.ПС + """a""""b"";c";
  249. Тесты = Тесты + Символы.ПС + """"""""";c";
  250. Тесты = Тесты + Символы.ПС + """;"";c";
  251. Тесты = Тесты + Символы.ПС + ";";
  252. Тесты = Тесты + Символы.ПС + "a;""b\nc"";d";
  253. Тесты = Тесты + Символы.ПС + "a;""b\nc;\n\nd;;\ne"";d";
  254. Тесты = Тесты + Символы.ПС + "a;""b""""\nc"""""";d";
  255. // неправильный формат
  256. Тесты = Тесты + Символы.ПС + "a;""b\n""с""";
  257. Тесты = Тесты + Символы.ПС + "a;""""b;"";""";
  258.  
  259. ТекстCSV = СтрЗаменить(СокрЛП(Тесты), "\n", Символы.ПС);
  260.  
  261. // инициализируем таблицу на форме
  262. тз = Новый ТаблицаЗначений;
  263. тз.Колонки.Добавить("Колонка1");
  264. тз.Колонки.Добавить("Колонка2");
  265. тз.Колонки.Добавить("Колонка3");
  266. тз.Добавить();
  267. ВывестиТаблицуНаФорму(ЭтаФорма, "ТаблицаCSV", тз);
  268.  
  269. ЭтаФорма.Разделитель = ",";
  270.  
  271. КонецПроцедуры
  272.  
  273. &НаКлиенте
  274. Процедура ПриОткрытии(Отказ)
  275. ПутьФайла_ПриИзменении();
  276. КонецПроцедуры
  277.  
  278. &НаКлиенте
  279. Процедура ПутьФайлаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
  280. СтандартнаяОбработка = Ложь;
  281.  
  282. Режим = РежимДиалогаВыбораФайла.Открытие;
  283. ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
  284. ДиалогОткрытияФайла.ПолноеИмяФайла = "";
  285. Фильтр = "Текст CSV (*.csv)|*.csv";
  286. ДиалогОткрытияФайла.Фильтр = Фильтр;
  287. ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
  288. ДиалогОткрытияФайла.Заголовок = "Выберите файл";
  289. Если ДиалогОткрытияФайла.Выбрать() Тогда
  290. ФайлДанных = Новый Файл(ДиалогОткрытияФайла.ПолноеИмяФайла);
  291. Если Найти(ФайлДанных.Имя, "-") ИЛИ
  292. Найти(ФайлДанных.Имя, " ") Тогда
  293. Предупреждение("В имени файла не дожно быть тире, пробелов и прочих недопустимых символов (как в имени переменной)!");
  294. Иначе
  295. ЭтаФорма.ПутьФайла = ДиалогОткрытияФайла.ПолноеИмяФайла;
  296. ПутьФайла_ПриИзменении();
  297. КонецЕсли;
  298. КонецЕсли;
  299.  
  300. КонецПроцедуры
  301.  
  302. &НаКлиенте
  303. Процедура Разделитель1ПриИзменении(Элемент)
  304. ПутьФайла_ПриИзменении();
  305. КонецПроцедуры
  306.  
  307. &НаСервере
  308. Процедура ПутьФайла_ПриИзменении()
  309. ФайлДанных = Новый Файл(ЭтаФорма.ПутьФайла);
  310. ФайлСхемы = Новый Файл(ФайлДанных.Путь+"Schema.ini");
  311. ЭтаФорма.Схема = "[" + ФайлДанных.Имя+ "]
  312. |ColNameHeader=False
  313. |Format=Delimited("+ЭтаФорма.Разделитель+")
  314. |TextDelimiter=none
  315. |CharacterSet=ANSI
  316. |";
  317. КонецПроцедуры
  318.  
  319. &НаСервере
  320. Процедура КомандаПреобразоватьCSVвТЗНаСервере()
  321. тз = ПреобразоватьТекстCSVвТЗ(ТекстCSV, ";");
  322. ВывестиТаблицуНаФорму(ЭтаФорма, "ТаблицаCSV", тз);
  323. КонецПроцедуры
  324.  
  325. &НаКлиенте
  326. Процедура КомандаПреобразоватьCSVвТЗ(Команда)
  327. КомандаПреобразоватьCSVвТЗНаСервере();
  328. КонецПроцедуры
  329.  
  330. &НаСервере
  331. Процедура КомандаПреобразоватьТЗвCSVНаСервере()
  332. тз = РеквизитФормыВЗначение("ТаблицаCSV");
  333. ТекстCSV = ПреобразоватьТЗвТекстCSV(тз, ";");
  334. КонецПроцедуры
  335.  
  336. &НаКлиенте
  337. Процедура КомандаПреобразоватьТЗвCSV(Команда)
  338. КомандаПреобразоватьТЗвCSVНаСервере();
  339. КонецПроцедуры
  340.  
  341. &НаКлиенте
  342. Процедура КомандаПрочитатьADO(Команда)
  343.  
  344. // подготовим Schema.ini
  345. ФайлДанных = Новый Файл(ЭтаФорма.ПутьФайла);
  346. ФайлСхемы = Новый Файл(ФайлДанных.Путь+"Schema.ini");
  347. ЗаписатьФайл(ФайлСхемы.ПолноеИмя, ЭтаФорма.Схема);
  348.  
  349. ЭтаФорма.ТабДок = ПрочитатьCSV_ADO(ЭтаФорма.ПутьФайла);
  350. КонецПроцедуры
  351.  
  352. &НаСервере
  353. Процедура КомандаПрочитатьGWFНаСервере()
  354. #Если ТолстыйКлиентОбычноеПриложение ИЛИ ТолстыйКлиентУправляемоеПриложение Тогда
  355. Время1 = ТекущаяУниверсальнаяДатаВМиллисекундах();
  356.  
  357. тз = ПрочитатьCSV_GWF(ЭтаФорма.ПутьФайла);
  358.  
  359. Время2 = ТекущаяУниверсальнаяДатаВМиллисекундах();
  360. Сообщить(""+(Время2-Время1)+" мс");
  361.  
  362. Элементы.Декорация1.Заголовок = "Считано записей:" + тз.Количество();
  363. #Иначе
  364. Сообщить("Компонента GameWithFire работает только в толстом клиенте!");
  365. #КонецЕсли
  366. КонецПроцедуры
  367.  
  368. &НаКлиенте
  369. Процедура КомандаПрочитатьGWF(Команда)
  370.  
  371. // подготовим Schema.ini
  372. ФайлДанных = Новый Файл(ЭтаФорма.ПутьФайла);
  373. ФайлСхемы = Новый Файл(ФайлДанных.Путь+"Schema.ini");
  374. ЗаписатьФайл(ФайлСхемы.ПолноеИмя, ЭтаФорма.Схема);
  375.  
  376. КомандаПрочитатьGWFНаСервере();
  377. КонецПроцедуры
Advertisement
Add Comment
Please, Sign In to add comment