[se] Handle errors cell helpers

This commit is contained in:
GoshaZotov
2026-03-19 00:15:50 +03:00
parent 0560ca1bd3
commit 7697b070d8
22 changed files with 1439 additions and 542 deletions

View File

@ -82,16 +82,37 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
if (params.numStdDev !== undefined && params.numStdDev !== null) {
if (typeof params.numStdDev !== 'number' || isNaN(params.numStdDev))
throw new window.AgentState.ToolError("Invalid numStdDev \"" + params.numStdDev + "\". Must be a number (e.g., 0, 1, 2).");
}
if (params.fillColor !== undefined && params.fillColor !== null) {
let r = params.fillColor.r, g = params.fillColor.g, b = params.fillColor.b;
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' ||
r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ||
!Number.isInteger(r) || !Number.isInteger(g) || !Number.isInteger(b))
throw new window.AgentState.ToolError("Invalid fillColor: r, g, b must each be integers between 0 and 255. Example: {\"r\": 255, \"g\": 0, \"b\": 0} for red.");
}
Asc.scope.range = params.range;
Asc.scope.aboveBelow = params.aboveBelow !== false; // default true
Asc.scope.numStdDev = params.numStdDev || 0;
Asc.scope.fillColor = params.fillColor;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.GetSelection();
}
@ -102,23 +123,25 @@
let formatConditions = range.GetFormatConditions();
let condition = formatConditions.AddAboveAverage();
if (condition) {
condition.SetAboveBelow(Asc.scope.aboveBelow);
if (Asc.scope.numStdDev !== 0) {
condition.SetNumStdDev(Asc.scope.numStdDev);
}
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(255, 165, 0);
condition.SetFillColor(defaultFillColor);
}
if (!condition)
return { error: "Failed to create above/below average conditional formatting rule for the specified range." };
condition.SetAboveBelow(Asc.scope.aboveBelow);
if (Asc.scope.numStdDev !== 0)
condition.SetNumStdDev(Asc.scope.numStdDev);
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(255, 165, 0);
condition.SetFillColor(defaultFillColor);
}
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -94,6 +94,30 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validOperators = ["xlGreater", "xlLess", "xlEqual", "xlNotEqual", "xlGreaterEqual", "xlLessEqual", "xlBetween", "xlNotBetween"];
if (params.operator !== undefined && params.operator !== null && !validOperators.includes(params.operator))
throw new window.AgentState.ToolError("Invalid operator \"" + params.operator + "\". Available options: " + JSON.stringify(validOperators));
function validateColor(color, paramName) {
if (color === undefined || color === null) return;
let r = color.r, g = color.g, b = color.b;
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' ||
r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ||
!Number.isInteger(r) || !Number.isInteger(g) || !Number.isInteger(b))
throw new window.AgentState.ToolError("Invalid " + paramName + ": r, g, b must each be integers between 0 and 255. Example: {\"r\": 255, \"g\": 0, \"b\": 0} for red.");
}
validateColor(params.fillColor, "fillColor");
validateColor(params.fontColor, "fontColor");
if ((params.operator === "xlBetween" || params.operator === "xlNotBetween") && params.value2 === undefined)
throw new window.AgentState.ToolError("Operator \"" + params.operator + "\" requires value2 parameter (the second boundary value).");
Asc.scope.range = params.range;
Asc.scope.operator = params.operator;
Asc.scope.value1 = params.value1;
@ -101,36 +125,41 @@
Asc.scope.fillColor = params.fillColor;
Asc.scope.fontColor = params.fontColor;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
let formatConditions = range.GetFormatConditions();
let condition = formatConditions.Add("xlCellValue", Asc.scope.operator, Asc.scope.value1, Asc.scope.value2);
if (condition) {
if (Asc.scope.fontColor) {
let fontColor = Api.CreateColorFromRGB(Asc.scope.fontColor.r, Asc.scope.fontColor.g, Asc.scope.fontColor.b);
let font = condition.GetFont();
if (font && font.SetColor) {
font.SetColor(fontColor);
}
}
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(255, 255, 0);
condition.SetFillColor(defaultFillColor);
if (!condition)
return { error: "Failed to create conditional formatting rule. Check that operator and value1 are valid." };
if (Asc.scope.fontColor) {
let fontColor = Api.CreateColorFromRGB(Asc.scope.fontColor.r, Asc.scope.fontColor.g, Asc.scope.fontColor.b);
let font = condition.GetFont();
if (font && font.SetColor) {
font.SetColor(fontColor);
}
}
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(255, 255, 0);
condition.SetFillColor(defaultFillColor);
}
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -77,6 +77,12 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
Asc.scope.chartType = params.chartType || "bar";
Asc.scope.title = params.title;

View File

@ -69,21 +69,38 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
Asc.scope.colorScaleType = params.colorScaleType || 3;
await Asc.Editor.callCommand(function() {
if (params.colorScaleType !== undefined && params.colorScaleType !== null && params.colorScaleType !== 2 && params.colorScaleType !== 3)
throw new window.AgentState.ToolError("Invalid colorScaleType \"" + params.colorScaleType + "\". Available options: " + JSON.stringify([2, 3]));
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
let formatConditions = range.GetFormatConditions();
formatConditions.AddColorScale(Asc.scope.colorScaleType);
let condition = formatConditions.AddColorScale(Asc.scope.colorScaleType);
if (!condition)
return { error: "Failed to create color scale conditional formatting rule." };
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -76,15 +76,36 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
if (params.threshold !== undefined && params.threshold !== null) {
if (typeof params.threshold !== 'number' || isNaN(params.threshold))
throw new window.AgentState.ToolError("Invalid threshold \"" + params.threshold + "\". Must be a number (e.g., 100).");
}
if (params.fillColor !== undefined && params.fillColor !== null) {
let r = params.fillColor.r, g = params.fillColor.g, b = params.fillColor.b;
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' ||
r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ||
!Number.isInteger(r) || !Number.isInteger(g) || !Number.isInteger(b))
throw new window.AgentState.ToolError("Invalid fillColor: r, g, b must each be integers between 0 and 255. Example: {\"r\": 255, \"g\": 0, \"b\": 0} for red.");
}
Asc.scope.range = params.range;
Asc.scope.threshold = params.threshold;
Asc.scope.fillColor = params.fillColor || {r: 255, g: 200, b: 200};
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
@ -111,14 +132,17 @@
let formatConditions = range.GetFormatConditions();
let condition = formatConditions.Add("xlCellValue", "xlGreater", threshold);
if (condition) {
let color = Asc.scope.fillColor ?
Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b) :
Api.CreateColorFromRGB(255, 200, 200);
condition.SetFillColor(color);
}
if (!condition)
return { error: "Failed to create conditional formatting rule." };
let color = Asc.scope.fillColor ?
Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b) :
Api.CreateColorFromRGB(255, 200, 200);
condition.SetFillColor(color);
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -59,9 +59,9 @@
},
"direction": {
"type": "string",
"description": "Direction of bars - 'leftToRight', 'rightToLeft' (default: 'leftToRight').",
"enum": ["leftToRight", "rightToLeft"],
"default": "leftToRight"
"description": "Direction of bars - 'xlLTR' (left to right), 'xlRTL' (right to left), 'xlContext' (context-based, default: 'xlLTR').",
"enum": ["xlContext", "xlLTR", "xlRTL"],
"default": "xlLTR"
}
},
"required": []
@ -83,41 +83,62 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validDirections = ["xlContext", "xlLTR", "xlRTL"];
if (params.direction !== undefined && params.direction !== null && !validDirections.includes(params.direction))
throw new window.AgentState.ToolError("Invalid direction \"" + params.direction + "\". Available options: " + JSON.stringify(validDirections));
if (params.barColor !== undefined && params.barColor !== null) {
let r = params.barColor.r, g = params.barColor.g, b = params.barColor.b;
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' ||
r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ||
!Number.isInteger(r) || !Number.isInteger(g) || !Number.isInteger(b))
throw new window.AgentState.ToolError("Invalid barColor: r, g, b must each be integers between 0 and 255. Example: {\"r\": 0, \"g\": 112, \"b\": 192} for blue.");
}
Asc.scope.range = params.range;
Asc.scope.barColor = params.barColor;
Asc.scope.showValue = params.showValue;
Asc.scope.direction = params.direction;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
let formatConditions = range.GetFormatConditions();
let databar = formatConditions.AddDatabar();
if (databar) {
if (Asc.scope.barColor) {
let barColor = Api.CreateColorFromRGB(Asc.scope.barColor.r, Asc.scope.barColor.g, Asc.scope.barColor.b);
databar.SetBarColor(barColor);
} else {
let defaultBarColor = Api.CreateColorFromRGB(70, 130, 180);
databar.SetBarColor(defaultBarColor);
}
if (typeof Asc.scope.showValue === "boolean") {
databar.SetShowValue(Asc.scope.showValue);
}
if (Asc.scope.direction) {
databar.SetDirection(Asc.scope.direction);
}
if (!databar)
return { error: "Failed to create data bar conditional formatting rule." };
if (Asc.scope.barColor) {
let barColor = Api.CreateColorFromRGB(Asc.scope.barColor.r, Asc.scope.barColor.g, Asc.scope.barColor.b);
databar.SetBarColor(barColor);
} else {
let defaultBarColor = Api.CreateColorFromRGB(70, 130, 180);
databar.SetBarColor(defaultBarColor);
}
if (typeof Asc.scope.showValue === "boolean")
databar.SetShowValue(Asc.scope.showValue);
if (Asc.scope.direction)
databar.SetDirection(Asc.scope.direction);
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -45,8 +45,9 @@
},
"iconSetType": {
"type": "string",
"description": "Type of icon set - 'threeArrows', 'threeTrafficLights', 'fourArrows', 'fiveArrows', etc. (default: 'threeArrows').",
"default": "threeArrows"
"description": "Type of icon set (default: 'xl3Arrows').",
"enum": ["xl3Arrows","xl3ArrowsGray","xl3Flags","xl3TrafficLights1","xl3TrafficLights2","xl3Signs","xl3Symbols","xl3Symbols2","xl4Arrows","xl4ArrowsGray","xl4RedToBlack","xl4CRV","xl4TrafficLights","xl5Arrows","xl5ArrowsGray","xl5CRV","xl5Quarters","xl3Stars","xl3Triangles","xl5Boxes"],
"default": "xl3Arrows"
},
"showIconOnly": {
"type": "boolean",
@ -68,7 +69,7 @@
},
{
"prompt": "Apply traffic lights icon set to range A1:D10",
"arguments": { "range": "A1:D10", "iconSetType": "threeTrafficLights" }
"arguments": { "range": "A1:D10", "iconSetType": "xl3TrafficLights1" }
},
{
"prompt": "When user asks to add icon set, arrow icons, traffic lights, symbols formatting",
@ -78,41 +79,49 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validIconSetTypes = ["xl3Arrows","xl3ArrowsGray","xl3Flags","xl3TrafficLights1","xl3TrafficLights2","xl3Signs","xl3Symbols","xl3Symbols2","xl4Arrows","xl4ArrowsGray","xl4RedToBlack","xl4CRV","xl4TrafficLights","xl5Arrows","xl5ArrowsGray","xl5CRV","xl5Quarters","xl3Stars","xl3Triangles","xl5Boxes"];
if (params.iconSetType !== undefined && params.iconSetType !== null && !validIconSetTypes.includes(params.iconSetType))
throw new window.AgentState.ToolError("Invalid iconSetType \"" + params.iconSetType + "\". Available options: " + JSON.stringify(validIconSetTypes));
Asc.scope.range = params.range;
Asc.scope.iconSetType = params.iconSetType;
Asc.scope.showIconOnly = params.showIconOnly;
Asc.scope.reverseOrder = params.reverseOrder;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.GetSelection();
}
if (!range) {
return;
}
let formatConditions = range.GetFormatConditions();
let iconSet = formatConditions.AddIconSetCondition();
if (iconSet) {
if (Asc.scope.iconSetType) {
iconSet.SetIconSet(Asc.scope.iconSetType);
}
if (typeof Asc.scope.showIconOnly === "boolean") {
iconSet.SetShowIconOnly(Asc.scope.showIconOnly);
}
if (typeof Asc.scope.reverseOrder === "boolean") {
iconSet.SetReverseOrder(Asc.scope.reverseOrder);
}
}
if (!iconSet)
return { error: "Failed to create icon set conditional formatting rule." };
if (Asc.scope.iconSetType)
iconSet.SetIconSet(Asc.scope.iconSetType);
if (typeof Asc.scope.showIconOnly === "boolean")
iconSet.SetShowIconOnly(Asc.scope.showIconOnly);
if (typeof Asc.scope.reverseOrder === "boolean")
iconSet.SetReverseOrder(Asc.scope.reverseOrder);
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -87,44 +87,67 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
if (params.rank !== undefined && params.rank !== null) {
if (typeof params.rank !== 'number' || isNaN(params.rank) || params.rank < 1)
throw new window.AgentState.ToolError("Invalid rank \"" + params.rank + "\". Must be a positive number (e.g., 10).");
}
if (params.fillColor !== undefined && params.fillColor !== null) {
let r = params.fillColor.r, g = params.fillColor.g, b = params.fillColor.b;
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' ||
r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ||
!Number.isInteger(r) || !Number.isInteger(g) || !Number.isInteger(b))
throw new window.AgentState.ToolError("Invalid fillColor: r, g, b must each be integers between 0 and 255. Example: {\"r\": 255, \"g\": 0, \"b\": 0} for red.");
}
Asc.scope.range = params.range;
Asc.scope.rank = params.rank || 10;
Asc.scope.isBottom = params.isBottom || false;
Asc.scope.isPercent = params.isPercent || false;
Asc.scope.fillColor = params.fillColor;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
let formatConditions = range.GetFormatConditions();
let condition = formatConditions.AddTop10();
if (condition) {
if (condition.SetRank) {
condition.SetRank(Asc.scope.rank);
}
if (condition.SetBottom) {
condition.SetBottom(Asc.scope.isBottom);
}
if (condition.SetPercent) {
condition.SetPercent(Asc.scope.isPercent);
}
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(144, 238, 144);
condition.SetFillColor(defaultFillColor);
}
if (!condition)
return { error: "Failed to create top/bottom conditional formatting rule." };
if (condition.SetRank)
condition.SetRank(Asc.scope.rank);
if (condition.SetBottom)
condition.SetBottom(Asc.scope.isBottom);
if (condition.SetPercent)
condition.SetPercent(Asc.scope.isPercent);
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(144, 238, 144);
condition.SetFillColor(defaultFillColor);
}
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -78,38 +78,57 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validDuplicateUnique = ["unique", "duplicate"];
if (params.duplicateUnique !== undefined && params.duplicateUnique !== null && !validDuplicateUnique.includes(params.duplicateUnique))
throw new window.AgentState.ToolError("Invalid duplicateUnique \"" + params.duplicateUnique + "\". Available options: " + JSON.stringify(validDuplicateUnique));
if (params.fillColor !== undefined && params.fillColor !== null) {
let r = params.fillColor.r, g = params.fillColor.g, b = params.fillColor.b;
if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number' ||
r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ||
!Number.isInteger(r) || !Number.isInteger(g) || !Number.isInteger(b))
throw new window.AgentState.ToolError("Invalid fillColor: r, g, b must each be integers between 0 and 255. Example: {\"r\": 255, \"g\": 0, \"b\": 0} for red.");
}
Asc.scope.range = params.range;
Asc.scope.duplicateUnique = params.duplicateUnique || 'duplicate';
Asc.scope.fillColor = params.fillColor;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
let formatConditions = range.GetFormatConditions();
let condition = formatConditions.AddUniqueValues();
if (!condition)
return { error: "Failed to create unique/duplicate values conditional formatting rule." };
if (condition) {
if (Asc.scope.duplicateUnique === 'unique') {
condition.SetDupeUnique("xlUnique");
} else {
condition.SetDupeUnique("xlDuplicate");
}
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(255, 192, 203);
condition.SetFillColor(defaultFillColor);
}
condition.SetDupeUnique(Asc.scope.duplicateUnique === "unique" ? "xlUnique" : "xlDuplicate");
if (Asc.scope.fillColor) {
let fillColor = Api.CreateColorFromRGB(Asc.scope.fillColor.r, Asc.scope.fillColor.g, Asc.scope.fillColor.b);
condition.SetFillColor(fillColor);
} else {
let defaultFillColor = Api.CreateColorFromRGB(255, 192, 203);
condition.SetFillColor(defaultFillColor);
}
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -63,20 +63,31 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
await Asc.Editor.callCommand(function() {
let result = await Asc.Editor.callCommand(function() {
let ws = Api.GetActiveSheet();
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
let formatConditions = range.GetFormatConditions();
formatConditions.Delete();
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -63,6 +63,12 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
let formulaData = await Asc.Editor.callCommand(function(){
@ -73,26 +79,32 @@
_range = Api.GetSelection();
} else {
_range = ws.GetRange(Asc.scope.range);
}
if (!_range || !_range.GetCells(1, 1)) {
return null;
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel cell address like 'A1'." };
}
let cell = _range.GetCells(1, 1);
if (!cell)
return { error: "Could not access cell in the specified range." };
let formula = cell.GetFormula();
let cellAddress = cell.GetAddress();
let hasFormula = !!(formula && formula.toString().startsWith('='));
if (!hasFormula)
return { error: "Cell " + cellAddress + " does not contain a formula. Its current value is: " + cell.GetValue() };
return {
formula: formula,
address: cellAddress,
hasFormula: formula && formula.toString().startsWith('=')
address: cellAddress
};
});
if (!formulaData || !formulaData.hasFormula) {
return; // No formula to explain
}
if (formulaData && formulaData.error)
throw new window.AgentState.ToolError(formulaData.error);
if (!formulaData)
return;
let argPrompt = "Explain the following Excel formula in detail:\n\n" +
"Formula: " + formulaData.formula + "\n" +

View File

@ -67,6 +67,12 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
let rangeData = await Asc.Editor.callCommand(function(){
@ -74,12 +80,20 @@
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
}
return [range.Address, range.GetValue2()];
});
if (rangeData && rangeData.error)
throw new window.AgentState.ToolError(rangeData.error);
if (!rangeData)
return;
//make csv from source data
let address = rangeData[0];
let data = rangeData[1];

View File

@ -67,6 +67,12 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
let rangeData = await Asc.Editor.callCommand(function(){
@ -77,6 +83,8 @@
_range = ws.GetUsedRange();
} else {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
}
if (!_range)
@ -103,6 +111,9 @@
}
});
if (formulaData.length === 0)
return { error: "No formulas found in the specified range." };
return {
formulas: formulaData,
startRow: startRow,
@ -110,9 +121,11 @@
};
});
if (!rangeData || !rangeData.formulas || rangeData.formulas.length === 0) {
if (rangeData && rangeData.error)
throw new window.AgentState.ToolError(rangeData.error);
if (!rangeData)
return;
}
let formulaData = rangeData.formulas;
let formulaValues = formulaData.map(function(item) { return item.cellValue; });
@ -176,7 +189,7 @@
});
}
} catch (error) {
console.error("Error parsing formula fix result:", error);
throw new window.AgentState.ToolError("Failed to parse AI response for formula fixes: " + error.message);
}
}

View File

@ -92,6 +92,16 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validColorSchemes = ["blue", "green", "orange", "gray", "red", "auto"];
if (params.colorScheme !== undefined && params.colorScheme !== null && !validColorSchemes.includes(params.colorScheme))
throw new window.AgentState.ToolError("Invalid colorScheme \"" + params.colorScheme + "\". Available options: " + JSON.stringify(validColorSchemes));
Asc.scope.range = params.range;
Asc.scope.applyHeaderStyle = params.applyHeaderStyle !== false; // default true
Asc.scope.applyBorders = params.applyBorders !== false; // default true
@ -100,23 +110,24 @@
await Asc.Editor.callMethod("StartAction", ["GroupActions", "Format table"]);
await Asc.Editor.callCommand(function(){
let result = await Asc.Editor.callCommand(function(){
let ws = Api.GetActiveSheet();
let _range;
if (!Asc.scope.range) {
if (Asc.scope.range) {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
_range = Api.GetSelection();
// If no selection, use the used range of the sheet
if (!_range || (_range.GetRowsCount() === 1 && _range.GetColumnsCount() === 1)) {
_range = ws.GetUsedRange();
}
} else {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "No range specified and the sheet appears to be empty. Please provide a range parameter (e.g., 'A1:D10')." };
}
if (!_range)
return;
let rowsCount = _range.GetRowsCount();
let colsCount = _range.GetColumnsCount();
@ -317,6 +328,9 @@
});
await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

View File

@ -80,6 +80,19 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
if (params.highlightColor !== undefined && params.highlightColor !== null) {
if (typeof params.highlightColor !== 'string' || params.highlightColor.trim() === '')
throw new window.AgentState.ToolError("Invalid highlightColor: must be a non-empty string. Use a hex color like '#FF0000' or a color name like 'red', 'yellow', 'blue'.");
if (params.highlightColor.startsWith('#') && !/^#[0-9A-Fa-f]{6}$/.test(params.highlightColor))
throw new window.AgentState.ToolError("Invalid highlightColor \"" + params.highlightColor + "\": hex color must be in '#RRGGBB' format (e.g., '#FF0000' for red).");
}
Asc.scope.range = params.range;
Asc.scope.highlightColor = params.highlightColor || "yellow";
@ -91,6 +104,8 @@
_range = Api.GetSelection();
} else {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
}
if (!_range)
@ -109,9 +124,11 @@
};
});
if (!rangeData || !rangeData.values) {
return;
}
if (rangeData && rangeData.error)
throw new window.AgentState.ToolError(rangeData.error);
if (!rangeData || !rangeData.values)
throw new window.AgentState.ToolError("Failed to retrieve data from the specified range.");
// Extract numeric values with their positions
let numericData = [];
@ -151,9 +168,8 @@
}
}
if (numericData.length === 0) {
return; // No numeric data to analyze
}
if (numericData.length === 0)
throw new window.AgentState.ToolError("No numeric data found in the specified range. Please select a range that contains numeric values.");
let dataValues = numericData.map(function(item) { return item.value; });

View File

@ -80,6 +80,19 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
if (params.highlightColor !== undefined && params.highlightColor !== null) {
if (typeof params.highlightColor !== 'string' || params.highlightColor.trim() === '')
throw new window.AgentState.ToolError("Invalid highlightColor: must be a non-empty string. Use a hex color like '#FF0000' or a color name like 'red', 'blue', 'orange'.");
if (params.highlightColor.startsWith('#') && !/^#[0-9A-Fa-f]{6}$/.test(params.highlightColor))
throw new window.AgentState.ToolError("Invalid highlightColor \"" + params.highlightColor + "\": hex color must be in '#RRGGBB' format (e.g., '#FF0000' for red).");
}
Asc.scope.range = params.range;
Asc.scope.highlightColor = params.highlightColor || "orange";

View File

@ -116,6 +116,19 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validOperators = ["xlAnd", "xlOr", "xlFilterValues", "xlTop10Items", "xlTop10Percent", "xlBottom10Items", "xlBottom10Percent", "xlFilterCellColor", "xlFilterFontColor", "xlFilterDynamic"];
if (params.operator !== undefined && params.operator !== null && !validOperators.includes(params.operator))
throw new window.AgentState.ToolError("Invalid operator \"" + params.operator + "\". Available options: " + JSON.stringify(validOperators));
if (Array.isArray(params.criteria2))
throw new window.AgentState.ToolError("Invalid criteria2: must be a string, not an array. Use criteria1 with xlFilterValues operator for multiple values.");
Asc.scope.range = params.range;
Asc.scope.field = params.field;
Asc.scope.fieldName = params.fieldName;
@ -129,15 +142,23 @@
let ws = Api.GetActiveSheet();
let _range;
if (!Asc.scope.range) {
_range = Api.GetSelection();
} else {
if (Asc.scope.range) {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
_range = Api.GetSelection();
}
return _range.GetValue2();
});
if (insertRes && insertRes.error)
throw new window.AgentState.ToolError(insertRes.error);
if (!insertRes)
throw new window.AgentState.ToolError("Failed to retrieve data from the specified range.");
let csv = insertRes.map(function(item){
return item.map(function(value) {
if (value == null) return '';
@ -187,27 +208,31 @@
Asc.scope.field = result;
}
await Asc.Editor.callCommand(function(){
// Use Asc.scope.field — may have been updated by the fieldName AI lookup above
if (Asc.scope.field !== undefined && Asc.scope.field !== null) {
let fieldNum = Number(Asc.scope.field);
if (isNaN(fieldNum) || fieldNum < 1 || !Number.isInteger(fieldNum))
throw new window.AgentState.ToolError("Invalid field \"" + Asc.scope.field + "\". Field must be a positive integer starting from 1 (left-most column).");
}
let filterResult = await Asc.Editor.callCommand(function(){
let ws = Api.GetActiveSheet();
let range;
if (!Asc.scope.range) {
range = Api.GetSelection();
} else {
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = Api.GetSelection();
if (!range)
return { error: "No range specified and no cells are currently selected. Please provide a range parameter (e.g., 'A1:D10')." };
}
if (!range) {
return;
}
let field = Asc.scope.field;
if (!field) {
field = 1;
}
let field = Asc.scope.field !== undefined ? Asc.scope.field : 1;
let criteria1 = Asc.scope.criteria1;
if (criteria1 && criteria1.startsWith && criteria1.startsWith("[") || criteria1.startsWith("{"))
if (criteria1 && criteria1.startsWith && (criteria1.startsWith("[") || criteria1.startsWith("{")))
criteria1 = eval(criteria1);
if (Asc.scope.operator === "xlFilterCellColor" || Asc.scope.operator === "xlFilterFontColor") {
if (criteria1 && typeof criteria1 === 'object' && criteria1.r !== undefined && criteria1.g !== undefined && criteria1.b !== undefined) {
@ -223,6 +248,9 @@
Asc.scope.visibleDropDown
);
});
if (filterResult && filterResult.error)
throw new window.AgentState.ToolError(filterResult.error);
};
return func;

View File

@ -99,6 +99,23 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validSortOrders = ["xlAscending", "xlDescending"];
const validHeaders = ["xlYes", "xlNo"];
if (params.sortOrder1 !== undefined && params.sortOrder1 !== null && !validSortOrders.includes(params.sortOrder1))
throw new window.AgentState.ToolError("Invalid sortOrder1 \"" + params.sortOrder1 + "\". Available options: " + JSON.stringify(validSortOrders));
if (params.sortOrder2 !== undefined && params.sortOrder2 !== null && !validSortOrders.includes(params.sortOrder2))
throw new window.AgentState.ToolError("Invalid sortOrder2 \"" + params.sortOrder2 + "\". Available options: " + JSON.stringify(validSortOrders));
if (params.sortOrder3 !== undefined && params.sortOrder3 !== null && !validSortOrders.includes(params.sortOrder3))
throw new window.AgentState.ToolError("Invalid sortOrder3 \"" + params.sortOrder3 + "\". Available options: " + JSON.stringify(validSortOrders));
if (params.header !== undefined && params.header !== null && !validHeaders.includes(params.header))
throw new window.AgentState.ToolError("Invalid header \"" + params.header + "\". Available options: " + JSON.stringify(validHeaders));
Asc.scope.range = params.range;
Asc.scope.key1 = params.key1;
Asc.scope.sortOrder1 = params.sortOrder1 || "xlAscending";
@ -115,15 +132,23 @@
let ws = Api.GetActiveSheet();
let _range;
if (!Asc.scope.range) {
_range = Api.GetSelection();
} else {
if (Asc.scope.range) {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
_range = Api.GetSelection();
}
return _range.GetValue2();
});
if (insertRes && insertRes.error)
throw new window.AgentState.ToolError(insertRes.error);
if (!insertRes)
throw new window.AgentState.ToolError("Failed to retrieve data from the specified range.");
let csv = insertRes.map(function(item){
return item.map(function(value) {
if (value == null) return '';

View File

@ -79,6 +79,19 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validSortOrders = ["xlAscending", "xlDescending"];
const validHeaders = ["xlYes", "xlNo"];
if (params.sortOrder1 !== undefined && params.sortOrder1 !== null && !validSortOrders.includes(params.sortOrder1))
throw new window.AgentState.ToolError("Invalid sortOrder1 \"" + params.sortOrder1 + "\". Available options: " + JSON.stringify(validSortOrders));
if (params.header !== undefined && params.header !== null && !validHeaders.includes(params.header))
throw new window.AgentState.ToolError("Invalid header \"" + params.header + "\". Available options: " + JSON.stringify(validHeaders));
Asc.scope.range = params.range;
Asc.scope.key1 = params.key1;
Asc.scope.sortOrder1 = params.sortOrder1 || "xlAscending";
@ -91,15 +104,23 @@
let ws = Api.GetActiveSheet();
let _range;
if (!Asc.scope.range) {
_range = Api.GetSelection();
} else {
if (Asc.scope.range) {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
_range = Api.GetSelection();
}
return _range.GetValue2();
});
if (insertRes && insertRes.error)
throw new window.AgentState.ToolError(insertRes.error);
if (!insertRes)
throw new window.AgentState.ToolError("Failed to retrieve data from the specified range.");
let csv = insertRes.map(function(item){
return item.map(function(value) {
if (value == null) return '';

View File

@ -63,6 +63,12 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
Asc.scope.range = params.range;
let rangeData = await Asc.Editor.callCommand(function(){
@ -70,12 +76,20 @@
let range;
if (Asc.scope.range) {
range = ws.GetRange(Asc.scope.range);
if (!range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
range = ws.Selection;
range = ws.Selection;
}
return [range.Address, range.GetValue2()];
});
if (rangeData && rangeData.error)
throw new window.AgentState.ToolError(rangeData.error);
if (!rangeData || !rangeData[1])
throw new window.AgentState.ToolError("Failed to retrieve data from the specified range.");
let address = rangeData[0];
let data = rangeData[1];
let colCount = data.length > 0 ? data[0].length : 0;

View File

@ -110,6 +110,21 @@
});
func.call = async function(params) {
if (params.range !== undefined && typeof params.range !== 'string') {
throw new window.AgentState.ToolError(
'Parameter "range" must be a string like "A1:D100". Got: ' + JSON.stringify(params.range)
);
}
const validUnderlines = ["none", "single", "singleAccounting", "double", "doubleAccounting"];
if (params.underline !== undefined && params.underline !== null && !validUnderlines.includes(params.underline))
throw new window.AgentState.ToolError("Invalid underline \"" + params.underline + "\". Available options: " + JSON.stringify(validUnderlines));
if (params.fontSize !== undefined && params.fontSize !== null) {
if (typeof params.fontSize !== 'number' || params.fontSize < 1 || params.fontSize > 200)
throw new window.AgentState.ToolError("Invalid fontSize \"" + params.fontSize + "\". Must be a number between 1 and 200.");
}
Asc.scope.bold = params.bold;
Asc.scope.italic = params.italic;
Asc.scope.underline = params.underline;
@ -119,19 +134,18 @@
Asc.scope.fontColor = params.fontColor;
Asc.scope.range = params.range;
await Asc.Editor.callCommand(function(){
let result = await Asc.Editor.callCommand(function(){
let ws = Api.GetActiveSheet();
let _range;
if (!Asc.scope.range) {
_range = Api.GetSelection();
} else {
if (Asc.scope.range) {
_range = ws.GetRange(Asc.scope.range);
if (!_range)
return { error: "Invalid range \"" + Asc.scope.range + "\". Please provide a valid Excel range like 'A1:D10'." };
} else {
_range = Api.GetSelection();
}
if (!_range)
return;
if (undefined !== Asc.scope.bold)
_range.SetBold(Asc.scope.bold);
@ -168,6 +182,9 @@
_range.SetFontColor(color);
}
});
if (result && result.error)
throw new window.AgentState.ToolError(result.error);
};
return func;

File diff suppressed because it is too large Load Diff