Skip to content

Instantly share code, notes, and snippets.

@cvillarongace
Last active January 31, 2022 14:13
Show Gist options
  • Save cvillarongace/7d178048bfe790037c8ca05c54f82159 to your computer and use it in GitHub Desktop.
Save cvillarongace/7d178048bfe790037c8ca05c54f82159 to your computer and use it in GitHub Desktop.
Creates a JSON string based on headers
name: Json From Headers
description: Creates a JSON string based on headers
host: EXCEL
api_set: {}
script:
content: |-
/**
* Evaluate a range of values and calculate a JSON string using headers as parents
* @customfunction
* @param {string[][]} fieldsRange
* @param {string[][]} valuesRange
* @returns JSON String.
*/
function rangeJSONTest(fieldsRange, valuesRange) {
const parents = fieldsRange.reverse();
/**
* Simple object check.
* @param item
* @returns {boolean}
*/
const isObject = (item) => {
return (item && typeof item === 'object' && !Array.isArray(item));
}
/**
* Deep merge two objects.
* @param target
* @param ...sources
*/
const mergeDeep = (target, ...sources) => {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, ...sources);
}
/*
Look for parent object
*/
const lookUpForParent = (row, fields, index) => {
if ((index < 0) || row > fields.length) {
return;
}
if ((row === 0) && (fields[row][index] == "")) {
return lookUpForParent(row + 1, fields, index);
}
if ((fields[row][index] == "") && (index >= 0)) {
return lookUpForParent(row, fields, index - 1);
}
return fields[row][index]
}
/*
Look for Preperty Name
*/
const lookUpForName = (row, fields, index, value) => {
const item = {};
const result = {};
if ((index < 0) || row > fields.length) {
return;
}
if ((row === 0) && (fields[row][index] == "")) {
return lookUpForName(row + 1, fields, index, value);
}
if ((fields[row][index] == "") && (index >= 0)) {
return lookUpForName(row, fields, index - 1, value);
}
item[fields[row][index]] = value;
if (row + 1 <= fields.length) {
const parent = lookUpForParent(row + 1, fields, index);
result[parent] = Object.assign({}, item);
}
return result
}
/*
Iterate Objects and headers
*/
const findParents = (parents, index, value) => {
let actualRow = 0;
let actualPos = index;
if (!isNaN(value)) {
var x = value;
var y: number = +x;
value = y;
}
let fieldName = lookUpForName(actualRow, parents, actualPos, value);
return fieldName;
};
let globalResult = {};
let values = valuesRange[0];
for (let _i = 0; _i < values.length; _i++) {
let value = values[_i];
if (value != "") {
const X = Object.assign({}, findParents(fieldsRange, _i, value));
globalResult = mergeDeep(globalResult, X);
}
}
return JSON.stringify(globalResult);
}
language: typescript
libraries: |
https://appsforoffice.microsoft.com/lib/1/hosted/office.js
@types/office-js
[email protected]/client/core.min.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment