Использование JavaScript для обработки данных в 1с

26.03.21

Разработка - Языки и среды

В статье мы передадим данные в JavaScript и получим результат обратно в 1С-объекты средствами JSON. Также "поиграем" с переданными данными.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Бесплатно
Использование JavaScript для обработки данных в 1с:
.epf 9,45Kb
245
245 Скачать бесплатно

Давайте передадим данные для обработки JavaScript, а результат вернем в 1С-объекты для дальнейшего использования уже в среде 1С. На практике такой подход можно применять в проектах связанных с web-технологиями например в таких как Яндекс карты 2.1. Построение маршрута. Передача длины маршрута в реквизит формы.

 

Создадим обработку для работы с данными. Добавим реквизит "HTML" с типом строка. В свойствах формы укажем вид "Поле HTML документа"

 

 

В модуле формы добавим несколько процедур.

Код HTML присваиваем переменной HTML. Подключаем обработчик ожидания через 0.1 секунды (обработчик срабатывает практически мгновенно).

 

 


&НаКлиенте
Процедура Тест(Команда)
	Макет = ПолучитьМакет("Макет");
	Данные = Макет.ПолучитьТекст();
	
	Скрипт = "
	|	const last = arr1.pop()
	|	const first = arr1.shift()
	|	arr1.splice(5,20)
	|	arr1.reverse()
	|	document.getElementById('body').innerHTML=JSON.stringify(arr1)
	|";
	
	HTML = "<!DOCTYPE html>
	|<html>
	|<head></head>
	|<body id='body'>
	|<script>
	|	arr1 = "+Данные+"
	|   "+Скрипт+"
	|</script>
	|</body>
	|</html>";
	ПодключитьОбработчикОжидания("ПолучитьРезультат", 0.1, истина);
	
КонецПроцедуры

Функция ПолучитьМакет(Макет)
	Обработка =  РеквизитФормыВЗначение("Объект");
	Возврат Обработка.ПолучитьМакет(Макет); 
КонецФункции

&НаКлиенте
Процедура ПолучитьРезультат()
	
	Попытка
		HTMLBody = Элементы.HTML.Документ.body.textContent;
		Стр = ИзJSON(HTMLBody);
		ТутЯСтавлюТочкуОстанова = 1;
	Исключение
		Сообщить(ОписаниеОшибки());
        //Если ошибка, то подключаю ОЖ еще раз через 1 секунду
		ПодключитьОбработчикОжидания("ПолучитьРезультат", 1, истина);
	КонецПопытки;	
	
КонецПроцедуры

Функция ИзJSON(СтрокаJSON) 
	ТекТоварыJSON = Новый ЧтениеJSON;
	ТекТоварыJSON.УстановитьСтроку(СтрокаJSON);
	Возврат ПрочитатьJSON(ТекТоварыJSON);
КонецФункции

 

Добавим в обработку макет (текстовый документ)

 

 

 
Данные в макет (Массив объектов или Массив структур)

В результате в поле HTML будут выводится JSON данные, которые сформировал JavaScript. В процедуре ПолучитьРезультат мы преобразуем JSON в 1с объекты.

 

 

Порадовал WebKit 1c, что он поддерживает ES6 синтаксис JavaScript(стрелочные функции и тд).

1. Получим и удалим первый и последний элемент. Далее удалим с 5 по 20 элемент массива и перевернем массив.

Метод shift() удаляет первый элемент из массива и возвращает его значение. 

Метод pop() удаляет последний элемент из массива и возвращает его значение.

Метод splice() изменяет содержимое массива, удаляя существующие элементы или добавляя новые.

Метод reverse() на месте обращает порядок следования элементов массива. Первый элемент массива становится последним, а последний — первым.

 

 

Скрипт = "	
	|	const first = arr1.shift()
	|	const last = arr1.pop()
	|	arr1.splice(5,20)
	|	arr1.reverse()
	|	document.getElementById('body').innerHTML=JSON.stringify(arr1)
	|";

2. Получим имена всех людей в структуру через запятую.

Метод map() создаёт новый массив с результатом вызова указанной функции для каждого элемента массива.

Метод join() объединяет все элементы массива в строку.

 

 

Скрипт = "
	|	const str = arr1.map(person=>person.name).join(', ')
	|	const names = {names:str}
	|	document.getElementById('body').innerHTML=JSON.stringify(names)
	|";

3. Найдем человека по имени.

Метод find() возвращает значение первого найденного в массиве элемента.

 

 

Скрипт = "
	|	const person = arr1.find(person=>person.name === 'Pauwels van Haverbeke')
	|	document.getElementById('body').innerHTML=JSON.stringify(person)
	|";

4. Получим людей у которых бюджет меньше 200000.

Метод filter() создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции.

 

 

Скрипт = "
	|	const arr2 = arr1.filter(person=>person.budget < 200000 )
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

5. Подсчитаем Сумму бюджета у мужчин и у женщин.

Метод reduce() применяет функцию к элементу массива, возвращая одно результирующее значение.

 

 

Скрипт = "
	|	const arr2 = arr1.reduce((prev, el) => {
	|	    prev[el.sex] += el.budget
	|	    return prev 
	|	}, {f:0,m:0})
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

6. Получим Два массива с возрастами мужчин и женщин.

Метод reduce очень хорош) Особенно открывает новые возможности применения, если в значение по умолчанию передавать не просто число, а массив или объект.

 

 

Скрипт = "
	|	const arr2 = arr1.reduce((prev, el) => {
	|	    prev[el.sex].push(el.age)
	|	    return prev 
	|	}, {f:[],m:[]})
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

7. Добавим в структуру новое свойство id со сгенерированным номером от 1000000 до 9000000.

Метод Math.random() возвращает псевдослучайное число с плавающей запятой из диапазона 0 до 1

 

 

Скрипт = "
	|	function getRandomArbitrary(min, max) {
	|        return Math.floor(Math.random() * (max - min) + min)
	|    }
	|    const arr2 = arr1.map(person=>{
	|        person.id = getRandomArbitrary(1000000, 9000000) 
	|        return person
	|    })
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

8. Отсортируем объекты по имени, переведем имена в верхний регистр, добавим номер по порядку.

Метод sort() на месте сортирует элементы массива и возвращает отсортированный массив.

 

 

	Скрипт = "
	|	const arr2 = arr1.sort((a, b) => a.name > b.name ? 1 : -1)
	|    .map((person,index)=>{
	|       person.name = person.name.toUpperCase()
	|       person.nomer = index+1
	|       return person
	|	 })
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

9. Получаем структуру структур по имени, чтобы структура корректно отражалось в 1с пробелы меняем на "_".

Метод forEach() выполняет указанную функцию один раз для каждого элемента в массиве.

 

 

Скрипт = "
	|	const byName = {}
	|	arr1.forEach(function (person) {
	|	    byName[person.name.replace(/ /g,'_')] = person
	|	})
	|	document.getElementById('body').innerHTML=JSON.stringify(byName)
	|";

10. Получим детей у которых есть родители в данном массиве.

 

 

	Скрипт = "
	|const byName = {}
	|arr1.forEach(function (person) {
	|    byName[person.name] = person
	|})
	|const keys2 = Object.keys(byName)
	|const arr2 = keys2
	|.map((key) => {
	|    if (byName[key].mother !== null) {
	|        if (byName[byName[key].mother] !== undefined) {
	|            return byName[key]
	|        }
	|    } 
	|    if (byName[key].father !== null) {
	|        if (byName[byName[key].father] !== undefined) {
	|            return byName[key]
	|        }
	|    }           
	|}).filter(person=> person!== undefined) 
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

 11. Получим женщин, которые являются матерями.

 

 

	Скрипт = "
	|const byName = {}
	|arr1.forEach(function (person) {
	|    byName[person.name] = person
	|})
	|
	|const keys2 = Object.keys(byName)
	|	const arr2 = keys2
	|    .map((key) => {
	|        const mother =
	|            byName[key].mother === null ? undefined : byName[byName[key].mother]
	|        return mother
	|    })
	|    .filter((mother) => mother !== undefined)
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

12. Получим массив возрастов отцов.

 

 

Скрипт = "
	|const byName = {}
	|arr1.forEach(function (person) {
	|    byName[person.name] = person
	|})
	|
	|const keys = Object.keys(byName)
	|const arr2 = keys
	|    .map((key) => {
	|        const father =
	|        byName[key].father === null ? undefined : byName[byName[key].father]
	|        return father !== undefined ? father.age : 0
	|    })
	|    .filter((value) => value > 0)
	|	document.getElementById('body').innerHTML=JSON.stringify(arr2)
	|";

13. Сгруппируем людей по возрасту.

 

 

Скрипт = "
	|var group = {}
	|	arr1.forEach(function (person) {
	|	  person.century = '_' + Math.ceil(person.age / 10) 
	|	  group[person.century] = []
	|	})
	|arr1.forEach(function (person) {
	|  group[person.century].push(person)
	|})
	|	document.getElementById('body').innerHTML=JSON.stringify(group)
	|";

 

P.S. Выкладывайте в комментариях свои скрипты, которые вы придумали с этими данными. 

 

Тестировал: 

Платформа 1С:Предприятие 8.3 (8.3.17.1851)

JavaScript обработка данные

См. также

Языки и среды Программист Платформа 1С v8.3 Бесплатно (free)

Будем писать свои скрипты на питоне и запускать их на 1С.

15.04.2024    4028    YA_418728146    13    

62

Мобильная разработка Языки и среды 1С:Элемент Программист Бесплатно (free)

Flutter может быть использован с 1С:Предприятием для разработки кроссплатформенных мобильных приложений, обеспечивая единый интерфейс и функциональность на устройствах под управлением iOS и Android. Это позволяет создавать приложения с высокой производительностью благодаря использованию собственного движка рендеринга Flutter. Интеграция Flutter с 1С:Предприятием позволяет создавать мобильные приложения любого уровня сложности, интегрировать их в корпоративные информационные системы, а также реализовывать бизнес-логику

19.03.2024    18310    ROk_dev    74    

43

Языки и среды Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Существует множество языков программирования, и каждый имеет свои особенности по работе с типами данных. Слабые, явные, динамические и другие... Но кто же здесь 1С и почему с приходом "строгой" типизации EDT 1С-программистам стоит задуматься над изменением своих привычек.

16.01.2024    7327    SeiOkami    25    

61

Языки и среды Программист Бесплатно (free)

Пример небольшого приложения, с которого можно начать изучать язык программирования Dart.

08.08.2023    4205    acvatoris    6    

15

Языки и среды Программист Платформа 1С v8.3 Россия Бесплатно (free)

Написание статического анализатора для 1С традиционным способом на Си.

30.06.2023    3496    prohorp    15    

12

Языки и среды Программист Абонемент ($m)

Поставили нам задачу - вынести на отдельный сервер функционал получения заказов от клиентов по электронной почте, парсинг полученных XLS в приемлемый вид и трансформация заказов в красивый JSON, понятный нашей учетной системе на 1С. Всю эту красоту желательно запустить в отдельном докер - контейнере, по возможности не тратя лицензии, поэтому отдельно стоящую конфигурацию на БСП отвергаем сразу. Можно было бы собрать всё на Apache Airflow или Apache NiFi, но решили попробовать реализовать всю логику без Open Source, будем делать свой ETL, с Исполнителем, который в версии 3.0 научился взаимодействовать с электронной почтой по IMAP. Начнем с середины - сначала напишем скрипты, а потом соберем их в рабочую конструкцию

1 стартмани

01.06.2023    2313    0    kembrik    2    

7

Языки и среды Программист Платформа 1С v8.3 Бесплатно (free)

При работе с 1С ORM (object relation mapping) все время преследует ощущение постоянного создания монолитного приложения — один раз привязался к какой либо сущности (например, справочник Контрагенты), и весь код заполнен ссылками на эту конкретную реализацию. Можно ли независимо разрабатывать в ORM совместимые между собой справочник «Контрагентов» и использующий его документ «Платежное поручение», но при этом избежать жестких зависимостей? Спасут ли нас микросервисы? Пример на аннотациях Java демонстрирует, как это возможно делать.

13.03.2023    1305    1CUnlimited    0    

3
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. informa1555 2715 02.01.21 14:10 Сейчас в теме
Я жабаскрипт вообще не знаю, но из того что я знаю круче всего обработка данных происходит на питоне. Вот если б питон прикрутить к 1С это был бы вообще агонь. Но все равно плюс.
zarubinpaul; kaliuzhnyi; +2 Ответить
2. s_vidyakin 68 02.01.21 16:49 Сейчас в теме
(1) питон так просто к формам не прикрутить, поэтому смысла в нем мало. А современный JS c ES6 почти ничем не отличается по работе с данными.
Для питона можно такой кейс интеграции описать - пишется на нем скрипт обработки данных, с полпинка поднимается http-сервер, 1С туда передает данные, а в ответ получает результат и выводит на форму. Было бы интересно сравнить расчет себестоимости через математический пакет numpy ) Если конечно имеет смысл после появления быстрого платформенного решения СЛАУ.
3. informa1555 2715 02.01.21 17:15 Сейчас в теме
(2) да это понятно с фласком там все будет работать или тензорфлоу через рест. Не я про другое немного - Вы пишете про парсинг json, а просто смотрю как в JS и как в питоне - в питоне все в 1 строку грубо говоря, да и вообще там много чего в 1 строку. И он как мне кажется создан для обработки данных - не даром же jupiter notebook. Вот я и подумал если бы не через rest а так взял из 1С выборку запроса, обработал питоном, упаковал в там же в json да и отправил куда надо там же (а то в 1С http запросы какие то тоже замороченные). Вот это было бы даа...
5. s_vidyakin 68 03.01.21 01:02 Сейчас в теме
(3) ради написания чего-то в одну строку не стоит заморачиваться )) Можно и в JS писать лапшу в одну строку, только нафига? Потом самому же сложнее будет разобраться через полгода. У 1С задач нет для обработки в питоне, он больше для математических задач, статистики, искуственного интеллекта. Это надо или очень большие объемы или сложные алгоритмы, у вас есть примеры таких задач, чтобы было оправдано применение питона?
13. webester 26 05.01.21 06:34 Сейчас в теме
(3) использовать фласк для того, что бы запустить вебсервер это все равно, что использовать 1С чтобы вывести сообщение пользователю
4. ksely 113 02.01.21 17:54 Сейчас в теме
(2) Я питон прикручивал к 1С через СОМ (см. pywin32). Пишешь на питоне СОМ-объект, регистрируешь его, потом их 1С вызываешь. Я так использовал готовые решения на Python для раскрашивания кода, перевода markdown в html и PDF в текст.
VyacheslavShilov; svilsa; Sorm; user1503726; +4 Ответить
10. pm74 203 04.01.21 18:00 Сейчас в теме
а что именно нужно прикрутить?
вот так сойдет
Прикрепленные файлы:
6. user1503726 03.01.21 01:06 Сейчас в теме
Имхо, для улучшения читабельности и понимания скрипты можно перенести все в текстовый макет и в коде как то выделять отдельные кусочки-скрипты.
Но проблема в том, что в рамках 1с нет возможности получить данные, пригодные для питона...
Залить в одну базу данные за несколько лет из разных источников - той же 1с, екселя, фокспро и собрать можно, но что и зачем? У пользователей 1с нет потребности в той информации, которую предлагает data science, а если есть, то это уже не 1с.
11. s_vidyakin 68 04.01.21 23:52 Сейчас в теме
(6) как это нет возможности? питон в основном с CSV работает, обычный текстовый файл с разделителями
12. user1503726 04.01.21 23:57 Сейчас в теме
(11) правильно, где вы в 1с увидите csv? Это база данных и уже даже не dbf..
Я допускаю что разово можно выгрузить из скд (самое примитивное что можно придумать, это остатки по бухучету со всеми реквизитами субконто в колонках, у меня в 7ке было такой конструктор, но даже самый большой справочник не превышал 7 тыс) в csv программно и прокрутить через алгоритмы питона.
В 7ке v7plus выполняла построчную запись, с скд тоже так можно и на клиенте или только на сервере?
14. John_d 5891 05.01.21 11:27 Сейчас в теме
(6) Насчет макетов согласен, но для стати мне было удобно размещать скрипты в форме и комментировать те которые ненужны в данный момент, чем создавать 13 макетов.
user1503726; +1 Ответить
7. SeiOkami 3515 03.01.21 07:58 Сейчас в теме
Интересно было бы посмотреть сравнения замеров времени. Насколько методы через JS будут выполняться быстрее/медленнее, чем платформенные 1С

За статью лайк
mkostya; CyberCerber; sashapere; u_n_k_n_o_w_n; asupsam; PowerBoy; Sorm; +7 Ответить
8. Sorm 56 03.01.21 10:11 Сейчас в теме
(7) Собственно, только это и интересно. Да, это все замечательно, но это что, делать основной технологии работы с массивами в каком-то решении? Внедрять всерьез?
"Ну, как эксперимент это интересно, но каково практическое применение?"(с)
16. John_d 5891 05.01.21 11:32 Сейчас в теме
(8) На практике такой подход можно применять в проектах связанных с web-технологиями например в таких как Яндекс карты 2.1. Построение маршрута. Передача длины маршрута в реквизит формы ( https://infostart.ru/public/988527/ )
sashapere; tchsn; fight1c; user1503726; +4 Ответить
17. Sorm 56 05.01.21 22:16 Сейчас в теме
(16) Да я видел заголовок:) Ничего против конкретных специализированных задач не имею:) Но в остальном...
18. Артано 795 06.01.21 10:11 Сейчас в теме
(7) JS выполняется на порядок быстрее, особенно если дело касается работы с математикой. Впрочем даже простые переборы коллекций отрабатывают быстрее. То есть, если в яве написать полностью независимый метод, который перелопатит кучу данных/сделает кучу вычислений и вернет результат, то накладные расходы на работу с внешним JS окупятся даже если JS будет через COM-объект работать.
VyacheslavShilov; fight1c; +2 Ответить
9. quazare 3800 03.01.21 16:35 Сейчас в теме
много статей "чисто экспериментальных" без особых практических применений, но это интересно с другой стороны - мол кто-то уже попробовал данную возможность
15. user1503726 05.01.21 11:31 Сейчас в теме
То есть справочник с полем неограниченной длины удобнее чем хранение текстовых и табличных документов в регистре сведений? Или это не принципиально..
19. kalyaka 1105 06.01.21 16:42 Сейчас в теме
Идея очень понравилась. Потенциал кажется очень высоким, есть куда развиваться :)

Немного критики. Код на JS лучше оформлять в специализированных редакторах, например в VS, тогда он будет выглядеть более канонически :). У языка JS очень сложная судьба и в последних версиях в него много чего добавили, но и старое осталось. И здесь очень важно выбрать для себя один стиль и придерживаться его, например: функциональный с использованием только чистых функций.

Не канонически:
- одновременно использовать функции map, reduce и forEach (п.9, п.10);
- использовать стрелочные функции и не стрелочные (п.9, п.7);
- в п.3 неоднозначная операция '=', правильно использовать '===';
- в п.5 функция не чистая, хотя впрочем стартовое значение не использует переменную, но все же (аналогично в п.6);
- смешение русского и английского в п.8
- отсутствие завершения операторов ";"

Еще раз повторюсь, идея в статье мне очень понравилась. Использование в своих решениях нескольких языков программирования, где бы каждый язык наилучшим образом подходил для решения своей задачи - думаю это тренд. Конечно у таких решений есть и свои недостатки... Один из них - необходимость знать разные языки.
20. John_d 5891 06.01.21 17:15 Сейчас в теме
(19) Спасибо за подробный разбор.
Пишу в VS копирую в 1с)
- одновременно использовать функции map, reduce и forEach
Почему плохо?
- использовать стрелочные функции и не стрелочные
Периодически требуется и то и другое. Стрелочная функция не влияет на this, а обычная делает свой this
- в п.3 неоднозначная операция '=', правильно использовать '===';
По невнимательности. Исправил.
- функция не чистая, хотя впрочем стартовое значение не использует переменную
Если вы про return. Тогда я не согласен. В стрелочных функциях тоже бывает return, если строчек больше чем одна.
- смешение русского и английского в п.8
Не сразу понял) nomer
- отсутствие завершения операторов ";"
";" в JS необязательные. Без них код чище.
21. kalyaka 1105 06.01.21 17:32 Сейчас в теме
(20)
";" в JS необязательные. Без них код чище
Однако это может порождать проблемы semi
- функция не чистая, хотя впрочем стартовое значение не использует переменную
Я про мутацию, return должна в чистом виде возвращать новый объект.
Периодически требуется и то и другое
Согласен, однако здесь я не вижу основания. Выглядит как старый код, когда можно писать по современному.
одновременно использовать функции map, reduce и forEach
Первые две предполагают использование чистых функций, а forEach - мутацию (не всегда, но в приведенных примерах)
Оставьте свое сообщение