
В прошлой статье мы рассмотрели как с помощью API Collaborator получать список людей, которые пользовались учебным порталом компании в заданный период. Теперь предлагаю рассмотреть реальный кейс.
Худенко Наталья, Руководитель Центра развития персонала производства, «Юрия-Фарм».
У них достаточно часто возникала потребность печати «Зачетной книжки» сотрудника. Важно было получить выборку за указанный период всех назначенных пользователю учебных заданий и статус обучения по ним – что пройдено, с каким результатом, а что в процессе. Результат нужен в электронной таблице, приятно оформленным и подготовленным к печати. Вот что примерно требовалось:

Как будем решать
Сделаем копию электронной таблицы, которая получает выборку пользователей, и используем ее как основу. Этот список будет источником данных для выбора сотрудника для которого нужно сформировать Зачетную книжку.
Преименуем лист «main» в «users» и добавим новый лист, ему дадим главное имя – «main» – он будет содержать результирующую таблицу данных. Оформим его, заполним примерами данных. На нем же разместим элементы формы запроса – поля для указания дат и выбора сотрудника плюс кнопки запуска обработки данных. У меня получилось вот так:

В коде скрипта main.gs выполним соотвествующие замены:
- добавим в main.gs переменную
var SHEET_USERS = SPREADSHEET.getSheetByName("users"); - заменим во всем коде SHEET_MAIN на SHEET_USERS.
- заменим название функции function main() на function getUsersList()
- заменим объявление переменных, которые хранят даты периода
var date_period_begin = SHEET_USERS.getRange('D1').getValue();
var date_period_end = SHEET_USERS.getRange('D2').getValue();
// заменим на..
var date_period_begin = SHEET_MAIN.getRange('D3').getValue();
var date_period_end = SHEET_MAIN.getRange('E3').getValue();
После этого желательно проверить – все ли работает? Запустим функцию getUsersList() и проверим, что список пользователей обновляется без ошибок.
Планируемая последовательность действий пользователя по работе с «Зачетной книжкой»:
1. Пользователь указывает период выборки данных в ячейках подписанных «Период обучения от – до».
2. Нажимает кнопку «Обновить список пользователей». При этом запускается код, что был описан в предыдущей статье. Он обновляет список пользователей на листе «users». Этот список является источником данных для выпадающего списка «Сотрудник».
- сделать выпадающий список в Google Spreadsheet: https://www.youtube.com/watch?v=SUt9L_onZGo
- сделать кнопку в Google Spreadsheet: https://www.youtube.com/watch?v=qX7pA28r7BI
- сделать выпадающий список в Excel: https://www.youtube.com/watch?v=2HcrhbPU43s
- сделать кнопку в Excel: https://ichip.ru/kak-sozdat-knopku-v-excel.html
3. Выбирает из списка «Сотрудник» нужного человека и нажимает кнопку «Заполнить книжку».
4. «Заполнить книжку» выполнит запрос на данные про выбранного человека, очистит книжку и заполнит ее результатами сотрудника по заданиям, которые попадают в указанный временной период.
Теперь заставим это все работать…
Готовим REST запросы
Нам потребуются 2 запроса:
– на данные выбранного пользователя (Имя, Фамилия, Должность, Подразделение, Фото). Все о пользователе отдает запрос к его профилю:
/api/rest.php/auth/users/<user_id>
– на выборку данных по заданиям из его «Истории обучения»:
/api/rest.php/tasks?page=1&count=<records_limit>&filter[date_assign]=<date_period_begin>&filter[date_assign]=<date_period_end>&sorting[date_assign]=desc&user_id=<user_id>&action=get-study-history-all-tasks
В этих запросах:
- <records_limit> – количество записей на странице выдачи результата;
- <date_period_begin> и <date_period_end> – даты периода в формате
"YYYY-MM-DD"; - <user_id> – идентификатор пользователя Collaborator.
Получение информации о пользователе
Получить данные указанного пользователя и разместить их на листе «Зачетной книжки» мы сможем этой функцией:
function getUserProfile(user_id){
checkJWT(); //check and udate JWT-key if nessesary
// /api/rest.php/auth/users/<user_id>
var requestURL = '/api/rest.php/auth/users/' + user_id;
var res = _getResByCollaboratorAPI(keyJWT, urlHome + requestURL);
if (JSON.stringify(res).substring(1, 6) == 'Error') {
Logger.log(JSON.stringify(res));
return 0;
}
// refill cells with user info
SHEET_MAIN.getRange('A4').setValue(res.fullname);
clearImages(); // clear photo
if (res.photo_thumb){
getImageFromURL(urlHome + res.photo_thumb); //get & insert photo_thumb
}
SHEET_MAIN.getRange('B8').setValue(res.position);
SHEET_MAIN.getRange('B9').setValue(res.department);
SHEET_MAIN.getRange('B10').setValue(res.city);
}
Эта функция кроме данных про ФИО, должность, подразделение и город человека еще получает и всталяет его фото.
Перед вставкой фото на лист выполняется очистка всех картинок на листе, кроме первой (это логотип компании – его не трогаем). Это делает функция:
function clearImages(){
var ReportSheet = SpreadsheetApp.getActive();
// Deletes all images (except image[0]) in a ReportSheet
var images = ReportSheet.getImages();
for (var i = 1; i < images.length; i++) {
images[i].remove();
}
}
Получение фото и вставка его на лист выполняется функцией:
function getImageFromURL(urlRequest){
var ReportSheet = SpreadsheetApp.getActive();
var sheet = SHEET_MAIN;
var img = UrlFetchApp.fetch(urlRequest).getBlob();
sheet.insertImage(img, 1, 5)
var images = sheet.getImages();
var img = images[images.length - 1];
var imgH = img.getHeight();
var imgW = img.getWidth();
var maxW = 150;
var newImgH = Math.round(imgH*(maxW/imgW));
img.setWidth(maxW)
.setHeight(newImgH)
.setAltTextTitle('Изображение')
.setAnchorCellYOffset(0)
.setAnchorCellXOffset(5);
}
Получение данных из истории обучения сотрудника
Из «Истории обучения» пользователя Collaborator нам нужно извлечь список заданий, у которых их дата назначения пользователю попадает в заданный период от <date_period_begin> до <date_period_end>.
Добавим переменную, которая будет хранить первую ячейку таблицы отчета.
var rngStartReport = SpreadsheetApp.getActive().getRangeByName('start_report');
Это именованная ячейка «start_report«. Относительно нее мы будем заполнять все остальные ячейки.
Функция заполнения отчета имеет вид:
function getUserLearningHistoryForPeriod(user_id, date_period_begin, date_period_end, records_limit) {
// get data of learning tasks for preset user who was assigned to this tasks in portal from <date_period_begin> to <date_period_end>
// example api request:
// api/rest.php/tasks?page=1&count=10&filter[date_assign]=2018-11-01&filter[date_assign]=2018-12-09&sorting[date_assign]=desc&user_id=3906&action=get-study-history-all-tasks
records_limit = records_limit || 1000;
var requestURL = '/api/rest.php/tasks?page=1&count=' + records_limit +
'&filter[date_assign]=' + dateToStr(date_period_begin) +
'&filter[date_assign]=' + dateToStr(date_period_end) +
'&sorting[date_assign]=desc&user_id=' + user_id +
'&action=get-study-history-all-tasks';
var res = _getResByCollaboratorAPI(keyJWT, urlHome + requestURL);
if (JSON.stringify(res).substring(1, 6) == 'Error') {
Logger.log(JSON.stringify(res));
return 0;
}
// fill cells in sheet "users"
SHEET_MAIN.getRange(rngStartReport.getRow(), 1, SHEET_MAIN.getLastRow(), 10).clearContent();
var rng = rngStartReport;
var data_tasks = res.data;
var accessdates = [];
data_tasks.forEach( function(item, i, data_tasks) {
rng.offset(i, 0).setValue(item.title);
rng.offset(i, 1).setValue(item.display_type);
rng.offset(i, 2).setValue(item.status);
rng.offset(i, 3).setValue(item.mark);
rng.offset(i, 4).setValue(item.date_assign);
//rng.offset(i, 5).setValue(item.date_start);
rng.offset(i, 5).setValue(item.date_finish);
});
}
Теперь осталось только определить <user_id> для выбранного из списка пользователя и все будет готово.
Определяем ID пользователя и получаем «Зачетную книжку»
Для работы запросов необходимо знать <user_id>. Вручную его вводить неудобно. Более «человечно» выбирать пользователя по его ФИО. И мы сделали выпадающий список, который помогает найти человека и выбрать его ФИО. Но это не дает нам нужный идентификатор. По-этому ради удобства использования прийдется немного поиграться…
В наборе функций Excel, в категории Ссылки и массивы (Lookup and reference) имеется функция ВПР (VLOOKUP). Она прекрасно решает задачу нахождения идентификатора. Подробно описано тут: https://www.planetaexcel.ru/techniques/2/106/index.php?page=user&id=11
VLOOKUP ищет по диаппазону ячеек строку с заданным значением (поисковой фразой) и возвращает значение из другого столбца этого диаппазона, но в той же строке. Есть нюанс: эта функция производит поиск только по первому столбцу диапазона. Поэтому нам надо будет изменить функцию получения списка пользователей, чтобы поменятьстолбцы местами:

Измененная функция заполнения списка пользователей:
function getUsersList() {
checkJWT();
var records_limit = 100;
var date_period_begin = SHEET_MAIN.getRange('D3').getValue();
var date_period_end = SHEET_MAIN.getRange('E3').getValue();
var requestURL = '/api/rest.php/auth/users?page=1&count=' + records_limit +
'&filter[last_activity]=' + dateToStr(date_period_begin) +
'&filter[last_activity]=' + dateToStr(date_period_end) +
'&sorting[last_activity]=desc';
var res = _getResByCollaboratorAPI(keyJWT, urlHome + requestURL);
if (JSON.stringify(res).substring(1, 6) == 'Error') {
Logger.log(JSON.stringify(res));
return 0;
}
SHEET_USERS.getRange(1, 1, 1000, 2).clearContent();
var rng = SHEET_USERS.getRange(1, 1);
var data_users = res.data;
data_users.forEach( function(item, i, data_users) {
rng.offset(i, 1).setValue(item.id);
rng.offset(i, 0).setValue(item.fullname);
});
}
В Google Spreadsheets есть полная аналогия функции ВПР (VLOOKUP). Подробно тут: https://support.google.com/docs/answer/3093318?hl=ru. Используем ее.
После перестановки столбцов не забудьте перенастроить правила проверки данных в ячейке с выпадающим списком на другой столбец (было users!B:B – исправляем на users!A:A).

На листе настроек добавим ячейку, которая будет содержать идентификатор пользователя Collaborator, которого мы выберем из выпадающего списка на «Зачетной книжке». Назначим ей имя «user_id«. В этой ячейке вставим формулу:
=VLOOKUP(main!D5;users!A:B;2;FALSE)

В коде скрипта значение из этой ячейки получаем так:
var user_id = SpreadsheetApp.getActive().getRangeByName('user_id').getValue();
Итоговая функция заполнения «Зачетной книжки» имеет вид:
function main(){
var user_id = SpreadsheetApp.getActive().getRangeByName('user_id').getValue();
var date_period_begin = SHEET_MAIN.getRange('D3').getValue();
var date_period_end = SHEET_MAIN.getRange('E3').getValue();
checkJWT(); //check and udate JWT-key if nessesary
getUserProfile(user_id);
getUserLearningHistoryForPeriod(user_id, date_period_begin, date_period_end);
}
И последний штрих. Надо назначить на нарисованные кнопки скрипты, которые им следует запускать:
- Кнопка «Обновить список пользователей» – скрипт getUsersList ;
- Кнопка «Заполнить книжку» – скрипт main .
Теперь можно пользоваться и вот как это работает:
Итог
Вот и добрались до практических и полезных задач. Этот пример работы через API с Collaborator можно легко развить в формирование сертификатов за обучение, подсчет «хитрого» рейтинга и т.д.
Использование MS Excel или Google Spreadsheets выгодно тем, что в руках у пользователя оказываются огромные возможности настройки внешнего вида отчетов, дополнительной обработки и визуализации данных. Кроме этого он можем распечатать или сохранить результат в удобном формате, самостоятельно настраивая все параметры и не ожидая помощи от программистов 🙂
Как всегда – полный код скрипта main со всеми функциями можно найти тут: https://github.com/mirgor/lmscollaborator_api_examples



































