function asc(str) { return str.charCodeAt(0); }
function chr(asciiCode) { return String.fromCharCode(asciiCode);}
function filterArray(sourceArray, match, include = true, caseInsensitive = false) {
return sourceArray.filter(item => {
if (typeof item !== 'string') {
return false;
}
// Приведение строки и критерия к нужному регистру, если нужно игнорировать регистр
const checkItem = caseInsensitive ? item.toLowerCase() : item;
const checkMatch = caseInsensitive ? match.toLowerCase() : match;
// Проверка на включение или исключение элементов
const containsMatch = checkItem.includes(checkMatch);
return include ? containsMatch : !containsMatch;
});
}
function instr(start = 1, string1, string2, caseInsensitive = false) {
// Приведение строк к нужному регистру, если нужно игнорировать регистр
const checkString = caseInsensitive ? string1.toLowerCase() : string1;
const searchString = caseInsensitive ? string2.toLowerCase() : string2;
// Поиск позиции первого вхождения
const position = checkString.indexOf(searchString, start - 1);
// Возвращаем позицию в 1-индексации или 0, если совпадение не найдено
return position !== -1 ? position + 1 : 0;
}
function instrRev(stringCheck, stringMatch, start = stringCheck.length, caseInsensitive = false) {
// Приведение строк к нужному регистру, если нужно игнорировать регистр
const checkString = caseInsensitive ? stringCheck.toLowerCase() : stringCheck;
const matchString = caseInsensitive ? stringMatch.toLowerCase() : stringMatch;
// Обрезаем строку до позиции start
const substring = checkString.slice(0, start);
// Находим последнюю позицию вхождения
const position = substring.lastIndexOf(matchString);
// Возвращаем позицию, если она больше 0, иначе возвращаем -1
return position !== -1 ? position + 1 : -1;
}
function join(arr, separator = ',') { return arr.join(separator); }
function lcase(str) { return str.toLowerCase(); }
function left(str, length) { return str.slice(0, length); }
function len(str) { return str.length; }
function ltrim(str) { return str.trimStart(); }
function mid(str, start, length) { // JavaScript строки индекс от 0, поэтому уменьшаем start на 1
// return str.substr(start - 1, length);
return str.substring(start - 1, start - 1 + length); }
function replaceAll(str, search, replacement) {
// Создаем регулярное выражение для поиска всех вхождений
// Используем глобальный флаг 'g' для замены всех вхождений
const regex = new RegExp(search.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'), 'g');
return str.replace(regex, replacement);
}
function right(str, length) {
if (length >= str.length) {
return str;
}
return str.substring(str.length - length);
}
function rtrim(str) { return str.replace(/\s+$/, ''); }
function space(n) { return ' '.repeat(n); }
function spc(n) { return ' '.repeat(n); }
function str(value) { return String(value); }
function strComp(string1, string2, compareMethod = 0) {
// если compareMethod == 1, регистр не важен
if (compareMethod === 1) {
string1 = string1.toLowerCase();
string2 = string2.toLowerCase();
}
if (string1 < string2) {
return -1;
} else if (string1 > string2) {
return 1;
} else {
return 0;
}
}
function repeatString(count, character) { return character.repeat(count); }
function strReverse(str) { return str.split('').reverse().join(''); }
function trim(str) { return str.trim(); }
function typeName(variable) {
if (variable === null) return "Null";
if (variable === undefined) return "Undefined";
const type = typeof variable;
switch (type) {
case "boolean":
return "Boolean";
case "number":
return Number.isInteger(variable) ? "Integer" : "Double";
case "string":
return "String";
case "function":
return "Function";
case "object":
if (Array.isArray(variable)) return "Array";
if (variable instanceof Date) return "Date";
return "Object";
default:
return "Unknown";
}
}
function ucase(str) { return str.toUpperCase(); }
function val(str) { // return parseInt(str);
function replaceAll(str, search, replacement) {
const regex = new RegExp(search.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'), 'g');
return str.replace(regex, replacement);
}
let s=parseFloat(str);
return replaceAll(String(s),".",",");//для ',' как десятичного разделителя
}
let array1 = [1, 2, 3]; // Массив с элементами 1, 2, 3
let array2 = new Array(1, 2, 3); // Массив с элементами 1, 2, 3, созданный через конструктор
//Вариант
function createArray(...elements) { return elements; }
let myArray = createArray(1, 2, 3, 4, 5); // Создаст массив [1, 2, 3, 4, 5]
function isArray(variable) { return Array.isArray(variable); }
function LBound(arr, dimension) {
if (!Array.isArray(arr)) {
throw new Error("Не массив");
}
// Проверка на измерение (в JavaScript массивы одномерные, поэтому проверка на измерение)
if (dimension && dimension !== 1) {
throw new Error("в JavaScript только одномерные массивы ");
}
// Возвращаемый начальный индекс для массива в JavaScript всегда 0
return 0;
}
function UBound(arr, dimension) {
if (!Array.isArray(arr)) {
throw new Error("Не массив!");
}
// Проверка на измерение (в JavaScript массивы одномерные, поэтому проверка на измерение)
if (dimension && dimension !== 1) {
throw new Error("в JavaScript только одномерные массивы");
}
// Возвращаем последний индекс массива
return arr.length - 1;
}
function CByte(expression) {
let number = Number(expression);
if (isNaN(number) || number < 0 || number > 255 || !Number.isInteger(number)) {
throw new Error("Invalid byte value");
}
return number;
}
function CCur(expression) {
let number = Number(expression);
if (isNaN(number)) {
throw new Error("Invalid currency value");
}
return number.toFixed(2); // Округляет до двух знаков после запятой для валюты
}
function CDate(dateString) {
const date = new Date(dateString);
// Проверка на корректность даты
if (isNaN(date)) {
throw new Error("Invalid date string");
}
return date;
}
function CDec(expression) {
let number = Number(expression);
if (isNaN(number)) {
throw new Error("Invalid number");
}
return number;
}
function CDbl(expression) {
let number = Number(expression);
if (isNaN(number)) {
throw new Error("Invalid number");
}
return number;
}
function CInt(expression) { return Math.round(Number(expression));}
function CLng(expression) { return parseInt(expression, 10); }
function CStr(expression) { return String(expression); }
function CSng(expression) { return parseFloat(expression);}
function toString(value) { return String(value); }
function toNumber(value) { return Number(value); }
function toBoolean(value) { return Boolean(value); }
function toObject(value) { return Object(value); }
function switchCase(expr, ...cases) {
for (let i = 0; i < cases.length; i += 2) {
const caseExpr = cases[i];
const caseValue = cases[i + 1];
if (expr === caseExpr) {
return caseValue;
}
}
// Если не найдено совпадений, возвращаем значение по умолчанию
return undefined;
}
const { exec } = require('child_process');
function shell(command, windowStyle) {
// Список возможных значений для windowStyle
const windowStyles = {
'hide': 0, // Скрытое окно
'normal': 1, // Обычное окно
'minimized': 2, // Свернутое окно
'maximized': 3 // Развернутое окно
};
// Устанавливаем параметры окна, если указано
let style = windowStyles[windowStyle] !== undefined ? windowStyles[windowStyle] : windowStyles['normal'];
// Запускаем команду
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Ошибка: ${error.message}`);
return;
}
if (stderr) {
console.error(`Стандартный поток ошибок: ${stderr}`);
return;
}
console.log(`Стандартный вывод: ${stdout}`);
});
}
// Пример использования
shell('notepad', 'normal'); // Запускает Notepad с обычным окном
function isNull(expression) { return expression === null || expression === undefined; }
function isMissing(arg) { return typeof arg === 'undefined';}
function isError(expression) { return expression instanceof Error;}
function isEmpty(expression) {
if (expression === undefined || expression === null || expression === "") {
return true;
}
if (Array.isArray(expression) && expression.length === 0) {
return true;
}
if (typeof expression === 'object' && Object.keys(expression).length === 0) {
return true;
}
return false;
}
//Макрос для Р7 с выводом в выбранную ячейку
function test(){
localStorage.setItem('MyApp.Settings.Theme', 'dark');
let rng=Api.GetActiveSheet().GetSelection();
rng.SetValue(getSetting('MyApp', 'Settings', 'Theme', 'light'));
}
function getSetting(appName, section, key, defaultValue) {
const storageKey = `${appName}.${section}.${key}`;
const value = localStorage.getItem(storageKey);
return value !== null ? value : defaultValue;
}
test();//dark
function getAllSettings(appName, section) {
const settings = {};
const prefix = `${appName}.${section}.`;
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key.startsWith(prefix)) {
const settingKey = key.substring(prefix.length);
settings[settingKey] = localStorage.getItem(key);
}
}
return settings;
}
// Определяем свой набор сообщений об ошибках
const errorMessages = {
1: "Ошибка: Недопустимый аргумент.",
2: "Ошибка: Доступ запрещен.",
3: "Ошибка: Элемент не найден.",
4: "Ошибка: Превышен лимит времени.",
5: "Ошибка: Недостаточно памяти.",
};
function getError(errorNumber) {
return errorMessages[errorNumber] || `Неизвестная ошибка: ${errorNumber}`;
}
function getErrorLine(error) {
if (error.stack) {
// Разбираем стек вызовов
const stackLines = error.stack.split('\n');
// Возвращаем первую строку стека, которая содержит номер строки ошибки
// Обычно это третья строка стека, но это может варьироваться
const lineInfo = stackLines[1].match(/:(\d+):\d+\)?$/);
if (lineInfo) {
return parseInt(lineInfo[1], 10);
}
}
return null;
}
function getEnvironmentVariable(name) { return process.env[name] || null;}
function doEvents(callback) {
setTimeout(callback, 0);
}
// Пример использования
console.log("Start");
doEvents(() => {
console.log("DoEvents callback");
});
console.log("End");
function createCustomError(errorNumber) {
let error = new Error(`Custom error with number: ${errorNumber}`);
error.number = errorNumber;
return error;
}
// Получение аргументов командной строки
const args = process.argv.slice(2); // slice(2) чтобы исключить первые два элемента (путь к Node.js и скрипту)
// Вывод аргументов
console.log("Command-line arguments:");
args.forEach((arg, index) => { console.log(`Argument ${index + 1}: ${arg}`); });
function callByName(object, methodName, args) {
if (typeof object[methodName] === 'function') {
// Если метод существует, вызываем его с переданными аргументами
return object[methodName](...args);
} else {
throw new Error(`Method ${methodName} does not exist on the object.`);
}
}
// Пример объекта с методами
const myObject = {
greet(name) {
return `Hello, ${name}!`;
},
add(a, b) {
return a + b;
}
};
// Использование функции callByName
try {
const greeting = callByName(myObject, 'greet', ['Alice']);
console.log(greeting); // Output: Hello, Alice!
const sum = callByName(myObject, 'add', [5, 3]);
console.log(sum); // Output: 8
} catch (error) {
console.error(error.message);
}
function RGB(red, green, blue) {
// Проверка, чтобы значения были в пределах от 0 до 255
if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) {
throw new Error('Values must be between 0 and 255');
}
// Преобразование в строку формата RGB
return `rgb(${red}, ${green}, ${blue})`;
}
function QBColor(index) {
// Палитра цветов QB64
const colors = [
"#000000", // 0: Black
"#FF0000", // 1: Red
"#00FF00", // 2: Green
"#FFFF00", // 3: Yellow
"#0000FF", // 4: Blue
"#FF00FF", // 5: Magenta
"#00FFFF", // 6: Cyan
"#C0C0C0", // 7: Light Gray
"#808080", // 8: Gray
"#FF0000", // 9: Red (same as index 1)
"#00FF00", // 10: Green (same as index 2)
"#FFFF00", // 11: Yellow (same as index 3)
"#0000FF", // 12: Blue (same as index 4)
"#FF00FF", // 13: Magenta (same as index 5)
"#00FFFF", // 14: Cyan (same as index 6)
"#FFFFFF" // 15: White
];
// Проверка, чтобы индекс был в допустимом диапазоне
if (index < 0 || index > 15) {
throw new Error('Index must be between 0 and 15');
}
return colors[index];
}
function VarType(value) {
if (value === null) return 'Null';
if (value === undefined) return 'Undefined';
if (typeof value === 'boolean') return 'Boolean';
if (typeof value === 'number') return 'Number';
if (typeof value === 'string') return 'String';
if (typeof value === 'object') {
if (Array.isArray(value)) return 'Array';
if (value instanceof Date) return 'Date';
return 'Object';
}
if (typeof value === 'function') return 'Function';
return 'Unknown';
}
function Oct(number) {
if (typeof number !== 'number' || isNaN(number) || !Number.isInteger(number)) {
throw new TypeError('Input must be an integer.');
}
return number.toString(8);
}
function Hex(number) {
if (typeof number !== 'number' || isNaN(number) || !Number.isInteger(number)) {
throw new TypeError('Input must be an integer.');
}
return number.toString(16).toUpperCase();
}
function IsObject(expression) { return typeof expression === 'object' && expression !== null;}
//Проверено в Р7
const myObject = { //Объект
name: 'John',
age: 30,
greet: function() {
console.log('Hello, ' + this.name);
}
};
// Доступ к свойствам объекта
console.log(myObject.name); // John
myObject.greet(); // Hello, John
const myElement = document.getElementById('myElementId');
console.log(myElement);
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log('Data from API:', data);
})
.catch(error => {
console.error('Error fetching data:', error);
});
const fs = require('fs');
// Чтение содержимого файла
fs.readFile('path/to/file.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}
console.log('File content:', data);
});
const fs = require('fs'); // Built-in Node.js module for file system operations
// Create an instance of a class from a Node.js module
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
function formatPercent(value, numDigitsAfterDecimal = 2, includeLeadingDigit = true, useParensForNegativeNumbers = false, groupDigits = false) {
// Convert value to a percentage
let percentage = (value * 100).toFixed(numDigitsAfterDecimal);
// Handle leading zero
if (!includeLeadingDigit && percentage.startsWith('0.')) {
percentage = percentage.slice(1); // Remove the leading zero
}
// Handle grouping of digits
if (groupDigits) {
let parts = percentage.split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); // Add commas for thousands
percentage = parts.join('.');
}
// Handle parentheses for negative numbers
if (useParensForNegativeNumbers && value < 0) {
percentage = `(${percentage})`;
} else if (value < 0) {
percentage = `-${percentage}`;
}
// Append percentage sign
return `${percentage}%`;
}
function formatNumber(value, numDigitsAfterDecimal = 2, includeLeadingDigit = true, useParensForNegativeNumbers = false, groupDigits = false) {
let formattedNumber = value.toFixed(numDigitsAfterDecimal);
// Обработка ведущего нуля
if (!includeLeadingDigit && formattedNumber.startsWith('0.')) {
formattedNumber = formattedNumber.slice(1); // Удаляем ведущий ноль
}
// Обработка группировки цифр (тысячные разделители)
if (groupDigits) {
let parts = formattedNumber.split('.'); // Разделяем целую и дробную части
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); // Добавляем запятые для тысячных
formattedNumber = parts.join('.'); // Соединяем части обратно
}
// Обработка скобок для отрицательных чисел
if (useParensForNegativeNumbers && value < 0) {
formattedNumber = `(${formattedNumber})`; // Оборачиваем отрицательное число в скобки
} else if (value < 0) {
formattedNumber = `-${formattedNumber}`; // Добавляем минус перед числом
}
return formattedNumber;
}
function formatDateTime(date, namedFormat) {
if (!(date instanceof Date)) {
throw new TypeError("Первый аргумент должен быть объектом Date.");
}
// Если формат не указан, используем формат по умолчанию (краткий формат даты и времени)
namedFormat = namedFormat || "short";
// Функция для добавления нулей в однозначные числа
const pad = (num) => num.toString().padStart(2, '0');
// Определяем форматирование в зависимости от указанного namedFormat
switch (namedFormat.toLowerCase()) {
case "short":
// Краткий формат даты и времени
return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${date.getFullYear()}
${pad(date.getHours())}:${pad(date.getMinutes())}`;
case "long":
// Длинный формат даты и времени
return `${date.getDate()} ${date.toLocaleString('default', { month: 'long' })} ${date.getFullYear()},
${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
case "shortdate":
// Краткий формат даты
return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${date.getFullYear()}`;
case "longdate":
// Длинный формат даты
return `${date.getDate()} ${date.toLocaleString('default', { month: 'long' })} ${date.getFullYear()}`;
case "shorttime":
// Краткий формат времени
return `${pad(date.getHours())}:${pad(date.getMinutes())}`;
case "longtime":
// Длинный формат времени
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
default:
throw new Error("Неизвестный формат даты/времени.");
}
}
function formatCurrency(expression, numDigitsAfterDecimal = 2, includeLeadingDigit = false,
useParensForNegativeNumbers = false, groupDigits = true) {
if (typeof expression !== 'number' || isNaN(expression)) {
throw new TypeError("Первый аргумент должен быть числом.");
}
// Создаем объект Intl.NumberFormat для форматирования чисел в денежном формате
const options = {
style: 'currency',
currency: 'USD', // Установите валюту по умолчанию, если необходимо
minimumFractionDigits: numDigitsAfterDecimal,
maximumFractionDigits: numDigitsAfterDecimal,
useGrouping: groupDigits
};
// Создаем экземпляр Intl.NumberFormat
const formatter = new Intl.NumberFormat('en-US', options);
// Форматируем число
let formattedNumber = formatter.format(expression);
// Если нужно добавить ведущий ноль, если число меньше 1
if (includeLeadingDigit && expression < 1 && expression > -1) {
formattedNumber = formattedNumber.replace(/^(?!\$\s*0)/, '$0');
}
// Если нужно использовать скобки для отрицательных чисел
if (useParensForNegativeNumbers && expression < 0) {
formattedNumber = formattedNumber.replace(/^\(\$/, '$(').replace(/\)$/, ')');
}
return formattedNumber;
}
function formatNumber(expression, format) {
if (typeof expression !== 'number' || isNaN(expression)) {
throw new TypeError("Первый аргумент должен быть числом.");
}
// Применяем форматирование чисел, если формат задан
if (format === 'currency') {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(expression);
} else if (format === 'percent') {
return new Intl.NumberFormat('en-US', { style: 'percent' }).format(expression);
} else if (format === 'fixed') {
return expression.toFixed(2); // Форматирование числа с двумя знаками после запятой
} else {
return expression.toString(); // По умолчанию просто преобразуем число в строку
}
}
function formatDate(expression, format, firstDayOfWeek = 0, firstWeekOfYear = 0) {
if (!(expression instanceof Date)) {
throw new TypeError("Первый аргумент должен быть объектом Date.");
}
const options = {
year: 'numeric',
month: '2-digit',
day: '2-digit'
};
if (format === 'shortDate') {
return new Intl.DateTimeFormat('en-US', options).format(expression);
} else if (format === 'longDate') {
return new Intl.DateTimeFormat('en-US', { ...options, weekday: 'long' }).format(expression);
} else if (format === 'time') {
return new Intl.DateTimeFormat('en-US', { hour: '2-digit', minute: '2-digit' }).format(expression);
} else {
return expression.toLocaleDateString(); // По умолчанию просто преобразуем дату в строку
}
}
function SYD(cost, salvage, life, period) {
// life - Полный срок службы актива
// cost - Первоначальная стоимость актива
// salvage - Остаточная стоимость актива в конце срока службы
// period - Период, для которого рассчитывается амортизация
if (life <= 0 || period <= 0 || period > life) {
throw new Error("Некорректные значения для срока службы или периода.");
}
// Рассчитываем количество лет
const sumOfYearsDigits = (life * (life + 1)) / 2;
// Рассчитываем амортизацию для указанного периода
const depreciation = ((cost - salvage) * (life - period + 1)) / sumOfYearsDigits;
return depreciation;
}
function SLN(cost, salvage, life) {
// life - Полный срок службы актива
// cost - Первоначальная стоимость актива
// salvage - Остаточная стоимость актива в конце срока службы
if (life <= 0) {
throw new Error("Срок службы должен быть больше нуля.");
}
// Рассчитываем амортизацию по методу прямолинейной амортизации
const depreciation = (cost - salvage) / life;
return depreciation;
}
function Rate(nper, pmt, pv, fv = 0, due = 0, guess = 0.1) {
// nper - Общее количество периодов
// pmt - Платеж за период
// pv - Приведенная стоимость (сумма займа)
// fv - Будущая стоимость (в конце).
// due - Тайминг платежей: 0 - конец периода, 1 - начало периода.
// guess - Начальное предположение для процентной ставки.
const epsMax = 1e-10; // Максимальная ошибка
const iterMax = 50; // Максимальное количество итераций
let y, y0, y1, x0, x1 = 0, f = 0, i = 0;
let rate = guess;
if (Math.abs(rate) < epsMax) {
y = pv * (1 + nper * rate) + pmt * (1 + rate * due) * nper + fv;
} else {
f = Math.exp(nper * Math.log(1 + rate));
y = pv * f + pmt * (1 / rate + due) * (f - 1) + fv;
}
y0 = pv + pmt * nper + fv;
y1 = pv * f + pmt * (1 / rate + due) * (f - 1) + fv;
x0 = 0.0;
x1 = rate;
i = y0 * y1 >= 0 ? 0 : 1;
while ((Math.abs(y0 - y1) > epsMax) && (i < iterMax)) {
rate = (y1 * x0 - y0 * x1) / (y1 - y0);
x0 = x1;
x1 = rate;
if (Math.abs(rate) < epsMax) {
y = pv * (1 + nper * rate) + pmt * (1 + rate * due) * nper + fv;
} else {
f = Math.exp(nper * Math.log(1 + rate));
y = pv * f + pmt * (1 / rate + due) * (f - 1) + fv;
}
y0 = y1;
y1 = y;
i++;
}
return rate;
}
function PV(rate, nper, pmt, fv = 0, type = 0) {
// nper - Общее количество периодов
// rate - Процентная ставка за период
// pmt - Платеж за период
// type - Тайминг платежей: 0 - конец периода, 1 - начало периода.
// fv - Будущая стоимость (в конце).
let pv;
if (rate === 0) {
pv = -pmt * nper - fv;
} else {
pv = (-pmt * (1 + rate * type) * (1 - Math.pow(1 + rate, -nper)) / rate - fv * Math.pow(1 + rate, -nper));
}
return pv;
}
function PPmt(rate, per, nper, pv, fv = 0, type = 0) {
// rate - Процентная ставка за период
// per - Период, для которого рассчитывается платеж
// nper - Общее количество периодов
// pv - Приведенная стоимость (сумма займа)
// fv - Будущая стоимость (в конце).
// type - Тайминг платежей: 0 - конец периода, 1 - начало периода.
const pmt = Pmt(rate, nper, pv, fv, type);
// Рассчитываем процентный платеж на данный период
let ipmt;
if (type === 1) {
if (per === 1) {
ipmt = 0;
} else {
ipmt = (pv * rate) * Math.pow(1 + rate, per - 2);
}
} else {
ipmt = (pv * rate) * Math.pow(1 + rate, per - 1);
}
// Возвращаем разницу между общим платежом и процентным платежом
return pmt - ipmt;
}
//Рассчитывает периодический платеж по аннуитету.
function Pmt(rate, nper, pv, fv = 0, type = 0) {
let pmt;
if (rate === 0) {
pmt = -(pv + fv) / nper;
} else {
pmt = - (pv * Math.pow(1 + rate, nper) + fv) * rate / ((1 + rate * type) * (Math.pow(1 + rate, nper) - 1));
}
return pmt;
}
function NPV(rate, valueArray) {
// rate - Дисконтная ставка за период
// {Array<number>} valueArray - Массив денежных потоков
// {number} - Чистая приведенная стоимость
if (!Array.isArray(valueArray)) {
throw new Error("valueArray should be an array");
}
let npv = 0;
for (let i = 0; i < valueArray.length; i++) {
npv += valueArray[i] / Math.pow(1 + rate, i + 1);
}
return npv;
}
function NPer(rate, pmt, pv, fv = 0, due = 0) {
if (rate === 0) {
return -(pv + fv) / pmt;
} else {
const adjustedRate = 1 + rate * due;
return Math.log((pmt * adjustedRate - fv * rate) / (pv * rate + pmt * adjustedRate)) / Math.log(1 + rate);
}
}
function MIRR(values, financeRate, reinvestRate) {
let npvPositive = 0;
let npvNegative = 0;
for (let i = 0; i < values.length; i++) {
if (values[i] > 0) {
npvPositive += values[i] / Math.pow(1 + reinvestRate, i);
} else {
npvNegative += values[i] / Math.pow(1 + financeRate, i);
}
}
if (npvNegative === 0 || npvPositive === 0) {
return 0;
}
const totalPeriods = values.length - 1;
const mirr =
Math.pow(-npvPositive * Math.pow(1 + reinvestRate, totalPeriods) / npvNegative, 1 / totalPeriods) - 1;
return mirr;
}
function IRR(values, guess = 0.1) {
const maxIteration = 1000;
const precision = 1e-7;
let rate = guess;
let iteration = 0;
let newRate;
while (iteration < maxIteration) {
let npv = 0;
let dNpV = 0;
for (let i = 0; i < values.length; i++) {
npv += values[i] / Math.pow(1 + rate, i);
dNpV -= (i * values[i]) / Math.pow(1 + rate, i + 1);
}
newRate = rate - npv / dNpV;
if (Math.abs(newRate - rate) < precision) {
return newRate;
}
rate = newRate;
iteration++;
}
throw new Error("IRR calculation did not converge");
}
function IPmt(rate, per, nper, pv, fv = 0, type = 0) {
if (per < 1 || per > nper) {
throw new Error("Период должен быть между 1 и общим количеством периодов (nper).");
}
// Рассчитываем общую сумму платежа (PMT)
const PMT = (rate !== 0)
? (pv * rate * Math.pow(1 + rate, nper) + fv * rate) / (Math.pow(1 + rate, nper) - 1)
: (pv + fv) / nper;
// Рассчитываем процентную часть платежа
const IPMT = (rate !== 0)
? (pv * Math.pow(1 + rate, per - 1)) * rate - (type === 1 ? PMT / (1 + rate) : 0)
: pv * rate;
return IPMT;
}
// Пример использования
const rate = 0.05 / 12; // Месячная процентная ставка
const per = 5; // Номер периода
const nper = 360; // Общее количество периодов
const pv = 100000; // Приведенная стоимость
const fv = 0; // Будущая стоимость (по умолчанию 0)
const type = 0; // Платеж в конце периода (по умолчанию 0)
console.log(IPmt(rate, per, nper, pv, fv, type)); // Результат: процентный платеж
function FV(rate, nper, pmt, pv = 0, due = 0) {
if (rate === 0) {
return -(pv + pmt * nper);
}
const typeAdjustment = due === 1 ? 1 : 0;
const futureValue = -((pv * Math.pow(1 + rate, nper)) + (pmt * (1 + rate * typeAdjustment) * ((Math.pow(1 + rate, nper) - 1) / rate)));
return futureValue;
}
function DDB(cost, salvage, life, period, factor = 2) {
let bookValue = cost;
let depreciation = 0;
for (let i = 1; i <= period; i++) {
depreciation = Math.min((bookValue * factor) / life, bookValue - salvage);
bookValue -= depreciation;
}
return depreciation;
}
function getYear(date) { return date.getFullYear();}
//Если firstDayOfWeek=1, то при weekday=1 возвращает Sunday, =2 Monday
function weekdayName(weekday, abbreviate = false, firstDayOfWeek = 1) {
const fullNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const shortNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
// Сдвигаем массив в зависимости от первого дня недели
const shiftedFullNames = fullNames.slice(firstDayOfWeek - 1).concat(fullNames.slice(0, firstDayOfWeek - 1));
const shiftedShortNames =
shortNames.slice(firstDayOfWeek - 1).concat(shortNames.slice(0, firstDayOfWeek - 1));
if (weekday < 1 || weekday > 7) {
throw new Error("Weekday must be between 1 and 7");
}
return abbreviate ? shiftedShortNames[weekday - 1] : shiftedFullNames[weekday - 1];
}
function weekday(date, firstDayOfWeek = 0) {
// {Date} date - Дата, для которой нужно определить номер дня недели.
// [firstDayOfWeek=0] - Первый день недели (0 для воскресенья)
// Проверка на корректность первого дня недели
if (firstDayOfWeek < 0 || firstDayOfWeek > 6) {
throw new Error("firstDayOfWeek must be between 0 and 6");
}
// Получаем номер дня недели, где 0 - воскресенье, 1 - понедельник, и т.д.
const day = date.getDay();
// Сдвигаем номер дня недели в зависимости от первого дня недели
const adjustedDay = (day - firstDayOfWeek + 7) % 7;
// Возвращаем номер дня недели, где 1 - первый день недели, 2 - второй, и т.д.
return adjustedDay + 1;
}
function timeValue(timeStr) {
// Проверка на корректность входной строки
if (typeof timeStr !== 'string') {
throw new Error("Input must be a string");
}
// Регулярное выражение для проверки и разбора строки времени
const timeRegex = /^(\d{2}):(\d{2})(:(\d{2}))?$/;
const match = timeStr.match(timeRegex);
if (!match) {
throw new Error("Invalid time format. Use 'HH:MM:SS' or 'HH:MM'");
}
const hours = parseInt(match[1], 10);
const minutes = parseInt(match[2], 10);
const seconds = match[4] ? parseInt(match[4], 10) : 0;
// Создаем объект Date для текущей даты, но с заданным временем
const now = new Date();
now.setHours(hours, minutes, seconds, 0);
return now;
}
function timeSerial(hour, minute, second) {
// Проверка валидности входных значений
if (typeof hour !== 'number' || typeof minute !== 'number' || typeof second !== 'number') {
throw new Error("Hour, minute, and second must be numbers");
}
if (hour < 0 || hour > 23) {
throw new Error("Hour must be between 0 and 23");
}
if (minute < 0 || minute > 59) {
throw new Error("Minute must be between 0 and 59");
}
if (second < 0 || second > 59) {
throw new Error("Second must be between 0 and 59");
}
// Создаем объект Date для текущей даты и устанавливаем заданное время
const now = new Date();
now.setHours(hour, minute, second, 0);
return now;
}
function timer() {
const now = new Date();
const midnight = new Date(now.toDateString()); // Создает объект Date на полночь текущего дня
const secondsSinceMidnight = (now - midnight) / 1000; // Разница в миллисекундах преобразована в секунды
return secondsSinceMidnight;
}
function currentTime() {
//String
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${hours}:${minutes}:${seconds}`;
}
function second(time) { return time.getSeconds();}
function currentDateTime() {
// Текущая дата и время в формате "ГГГГ-ММ-ДД ЧЧ:ММ:СС"
const now = new Date();
// Получение частей даты и времени
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // Месяцы начинаются с 0
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
// Форматирование в строку
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
function monthName(month, abbreviate = false) {
// Проверка на допустимость номера месяца
if (month < 1 || month > 12) {
throw new Error('Номер месяца должен быть в диапазоне от 1 до 12.');
}
// Массив полных названий месяцев
const fullMonthNames = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
// Массив сокращённых названий месяцев
const abbreviatedMonthNames = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
// Выбор массива названий в зависимости от параметра abbreviate
const monthNames = abbreviate ? abbreviatedMonthNames : fullMonthNames;
return monthNames[month - 1];
}
function getMonth(date) {
if (!(date instanceof Date)) {
throw new TypeError('Аргумент должен быть объектом Date.');
}
// Месяцы в JavaScript индексируются с 0, поэтому добавляем 1
return date.getMonth() + 1; // 1..12
}
function getMinutes(date) {
if (!(date instanceof Date)) {
throw new TypeError('Аргумент должен быть объектом Date.');
}
return date.getMinutes();
}
function isDate(value) {
const date = new Date(value);
// Проверяем, является ли дата допустимой и соответствует ли она исходному значению
return !isNaN(date.getTime()) && value !== '';
}
function getHour(time) {
// Создаем объект Date, если time является строкой
const date = (typeof time === 'string') ? new Date(`1970-01-01T${time}Z`) : new Date(time);
// Проверяем, является ли date допустимым объектом Date
if (isNaN(date.getTime())) {
throw new Error('Invalid date or time value');
}
return date.getUTCHours(); // Используем getUTCHours для получения часа в пределах от 0 до 23
}
function getDay(date) { return date.getDate();}
function dateValue(dateString) {
const dateObj = new Date(dateString);
// Проверяем, является ли dateObj допустимым объектом Date
if (isNaN(dateObj.getTime())) {
throw new Error('Invalid date string');
}
// Устанавливаем время в 00:00:00, если нужно только дату без времени
dateObj.setHours(0, 0, 0, 0);
return dateObj;
}
function dateSerial(year, month, day) {
// Поскольку в JavaScript месяцы начинаются с 0, мы вычитаем 1 из месяца
const dateObj = new Date(year, month - 1, day);
// Проверяем, является ли dateObj допустимым объектом Date
if (isNaN(dateObj.getTime())) {
throw new Error('Invalid date values');
}
return dateObj;
}
function datePart(interval, date, firstDayOfWeek = 0, firstWeekOfYear = 0) {
switch (interval.toLowerCase()) {
case 'yyyy':
return date.getFullYear();
case 'q': // Определяем квартал по месяцу
const month = date.getMonth();
return Math.floor(month / 3) + 1;
case 'm':
return date.getMonth() + 1; // Месяцы в JavaScript начинаются с 0
case 'd':
return date.getDate();
case 'w':
return date.getDay(); // В JavaScript неделя начинается с воскресенья (0)
case 'y': // День года, т.е. сколько дней прошло с начала года
const startOfYear = new Date(date.getFullYear(), 0, 1);
return Math.ceil((date - startOfYear) / (24 * 60 * 60 * 1000)) + 1;
case 'ww': // Определение номера недели года
const startOfYearWeek = new Date(date.getFullYear(), 0, 1);
const weekDiff = (date - startOfYearWeek) / (7 * 24 * 60 * 60 * 1000);
return Math.ceil(weekDiff) + 1;
default:
throw new Error('Invalid interval specified');
}
}
function dateDiff(interval, date1, date2, firstDayOfWeek = 0, firstWeekOfYear = 0) {
// Убедимся, что date1 и date2 являются объектами Date
if (!(date1 instanceof Date) || !(date2 instanceof Date)) {
throw new Error('date1 and date2 must be Date objects');
}
// Вычисление разницы в миллисекундах
const diffInMs = date2 - date1;
// Определяем интервал
switch (interval.toLowerCase()) {
case 'y': // Годы
return date2.getFullYear() - date1.getFullYear();
case 'm': // Месяцы
return (date2.getFullYear() - date1.getFullYear()) * 12 + (date2.getMonth() - date1.getMonth());
case 'd': // Дни
return Math.floor(diffInMs / (1000 * 60 * 60 * 24));
case 'h': // Часы
return Math.floor(diffInMs / (1000 * 60 * 60));
case 'n': // Минуты
return Math.floor(diffInMs / (1000 * 60));
case 's': // Секунды
return Math.floor(diffInMs / 1000);
default:
throw new Error('Invalid interval specified');
}
}
function dateAdd(interval, number, date) {
// Убедимся, что date является объектом Date
if (!(date instanceof Date)) {
throw new Error('date must be a Date object');
}
// Создаем копию исходной даты
const newDate = new Date(date);
// Добавляем интервал в зависимости от типа
switch (interval.toLowerCase()) {
case 'days':
newDate.setDate(newDate.getDate() + number);
break;
case 'months':
newDate.setMonth(newDate.getMonth() + number);
break;
case 'years':
newDate.setFullYear(newDate.getFullYear() + number);
break;
case 'hours':
newDate.setHours(newDate.getHours() + number);
break;
case 'minutes':
newDate.setMinutes(newDate.getMinutes() + number);
break;
case 'seconds':
newDate.setSeconds(newDate.getSeconds() + number);
break;
default:
throw new Error('Invalid interval specified');
}
return newDate;
}
function getCurrentDate() {
const now = new Date();
// Устанавливаем время на полночь
now.setHours(0, 0, 0, 0);
return now;
}
function getObjectReference(obj) { // Возвращает ссылку на объект
return obj;
}
const weakMap = new WeakMap();
test_refwm();
function storeObject(obj) {
// Использование WeakMap для хранения объекта
weakMap.set(obj, true);
}
function test_refwm(){
// Пример использования
const myObject = { value: 42 };
storeObject(myObject);
// Проверка, существует ли объект в WeakMap
console.log(weakMap.has(myObject)); // true
}
const str = "Hello, World!";
const anotherStr = str;
console.log(anotherStr); // "Hello, World!"
const stringMap = new Map();
test_map();
function storeString(key, value) {
stringMap.set(key, value);
}
function test_map(){
// Пример использования
const key = "uniqueKey";
const value = "Hello, World!";
storeString(key, value);
// Получение строки из Map
console.log(stringMap.get(key)); // "Hello, World!"
}
const strings = {
first: "Hello",
second: "World"
};
test_ident();
function test_ident(){
const identifier = "first";
console.log(strings[identifier]); // "Hello"
}
const strObj = String("Hello, World!");
test_str();
function test_str(){
console.log(strObj.toString()); // "Hello, World!"
}
const objectMap = new Map();
test_set();
function test_set(){
// Пример использования
const key = "uniqueObject";
const obj = { name: "Example" };
console.log("test_set store");
objectMap.set(key, obj);
// Получение объекта из Map
console.log(objectMap.get(key)); // { name: "Example" }
}
test_obj();
function test_obj(){
const obj1 = { name: "Object1" };
const obj2 = obj1; // obj2 и obj1 указывают на один и тот же объект
console.log(obj2.name); // "Object1"
}
const weakMap = new WeakMap();
test_wmobj();
function test_wmobj(){
// Пример использования WeakMap
const key = {};
const obj = { name: "WeakObject" };
weakMap.set(key, obj);
// Получение объекта из WeakMap
console.log(weakMap.get(key)); // { name: "WeakObject" }
}
const objects = {};
test_objmet();
function addMetadata(id, obj) {
objects[id] = obj;
}
function test_objmet(){
// Пример использования
const id = "metaObject";
const obj = { name: "MetadataObject" };
addMetadata(id, obj);
// Получение объекта из метаданных
console.log(objects[id]); // { name: "MetadataObject" }
}
test_confirm();
//test_alert();
function test_alert(){
Common.UI.alert({msg: "Привет"});
}
function test_confirm(){
const userResponse = Common.UI.confirm({ title: "Заголовок", msg: "Hello, msg",
callback: fconfirm,
buttons: [
{ caption: "Да", value: "yes" },
{ caption: "Нет", value: "no" },
],
});
}
function fconfirm(ret){
console.log(`Пользователь выбрал ${ ret }`);
}
{
"1001": "Hello, World!",
"1002": "Welcome to our application.",
"1003": "An error occurred. Please try again later."
}
fetch('resources.json')
.then(response => response.json())
.then(data => {
// Функция для получения строки ресурса по идентификатору
function loadResString(id) {
return data[id] || "Resource not found.";
}
// Пример использования функции
const message = loadResString("1001");
console.log(message); // Выведет: Hello, World!
})
.catch(error => console.error('Error loading resources:', error));
{
"2001": "/images/image1.png",
"2002": "/images/image2.jpg"
}
function loadResPicture(id) {
return fetch('resources.json')
.then(response => response.json())
.then(data => {
const imagePath = data[id];
if (imagePath) {
return fetch(imagePath)
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob));
}
throw new Error('Resource not found.');
})
.catch(error => console.error('Error loading resource:', error));
}
// Пример использования функции
loadResPicture("2001")
.then(imgUrl => {
document.getElementById('myImage').src = imgUrl;
});
{
"data1": {
"type": "text",
"path": "/resources/data1.txt"
},
"data2": {
"type": "json",
"path": "/resources/data2.json"
}
}
Загрузка из файла
async function loadResData(id, type) {
try {
// Загрузка метаданных о ресурсах
const response = await fetch('/path/to/resources.json');
const resources = await response.json();
const resource = resources[id];
if (resource && resource.type === type) {
const dataResponse = await fetch(resource.path);
if (type === 'text') {
return await dataResponse.text();
} else if (type === 'json') {
return await dataResponse.json();
}
}
throw new Error('Resource not found or type mismatch.');
} catch (error) {
console.error('Error loading resource:', error);
}
}
// Пример использования функции
loadResData('data1', 'text').then(data => {
console.log(data); // Вывод текста из ресурса
});
loadResData('data2', 'json').then(data => {
console.log(data); // Вывод данных из JSON
});
// 1.Тернарный оператор
let result = (number % 2 === 0) ? "Even" : "Odd";
// 2.Функция
function iIf(condition, truePart, falsePart) { return condition ? truePart : falsePart;}
function choose(index, ...items) {
// Check if the index is within the valid range
if (index < 1 || index > items.length) {
throw new Error("Index out of range");
}
return items[index - 1];
}