Can't Use Entire Column Range with Excel JavaScript API - excel

I've been working with entire Col rng's and noticed some inconsistencies.
For instance, my Excel Spreadsheet has a Col Rng of A1:A1048576, but the following code fails.
var ws = context.workbook.worksheets.getActiveWorksheet();
var range = ws.getRange("A1:A1048576");
range.values = "A";
But, if I use the rng as "A1:A1048575" (minus one), it works. Am I doing something wrong? The RNG doesn't appear to be 0 indexed as A1 selects the correct cell. I suspect this might be a bug, but wanted to confirm.
Here is the error FYI:
InvalidOperation: This operation is not permitted for the current object.
{
[functions]: ,
__proto__: {
[functions]: ,
__proto__: {
[functions]: ,
__proto__: {
[functions]: ,
__proto__: null
},
message: "",
name: "Error",
Symbol()_7.rurcc9qe7b1: undefined,
Symbol(nodejs.util.inspect.custom)_j.rurcc9qe7hi: undefined
},
message: "",
name: "Error",
Symbol()_7.rurcc9qe7b1: undefined,
Symbol(nodejs.util.inspect.custom)_j.rurcc9qe7hi: undefined
},
code: "InvalidOperation",
data: undefined,
debugInfo: {
[functions]: ,
__proto__: { },
code: "InvalidOperation",
errorLocation: "Range.values",
fullStatements: [
0: "Please enable config.extendedErrorLogging to see full statements.",
length: 1
],
message: "This operation is not permitted for the current object.",
statement: "range.values = ...;",
surroundingStatements: [
0: "var workbook = context.workbook;",
1: "var worksheets = workbook.worksheets;",
2: "var activeWorksheet = worksheets.getActiveWorksheet();",
3: "var range = activeWorksheet.getRange(...);",
4: "// Instantiate {range}",
5: "// >>>>>",
6: "range.values = ...;",
7: "// <<<<<",
length: 8
],
Symbol()_7.rurcc9qe7b1: undefined,
Symbol(nodejs.util.inspect.custom)_j.rurcc9qe7hi: undefined
},
description: "This operation is not permitted for the current object.",
httpStatusCode: 400,
innerError: null,
message: "This operation is not permitted for the current object.",
name: "RichApi.Error",
stack: "InvalidOperation: This operation is not permitted for the current object.
at Anonymous function (https://appsforoffice.microsoft.com/lib/beta/hosted/excel-win32-16.01.js:26:305431)
at Anonymous function (http://localhost:3000/yo/dist/polyfill.js:1:76119)
at e (http://localhost:3000/yo/dist/polyfill.js:1:31843)",
Symbol()_7.rurcc9qe7b1: undefined,
Symbol(nodejs.util.inspect.custom)_j.rurcc9qe7hi: undefined,
traceMessages: [
length: 0
]
}

Let me give a detailed answer.
Normally, we use range.values should like this:
range.values=[["A"]] the value is a 2-d array.
As shown in the api doc: https://learn.microsoft.com/en-us/javascript/api/excel/excel.range?view=excel-js-preview#excel-excel-range-values-member
I tested your way and it did runs. So I would suppose we also support this kind of input.
And for your issue, yes I can repro it. And I have a workaround now.
var ws = context.workbook.worksheets.getActiveWorksheet();
var range = ws.getRange("A1:A1048575");
range.values = "A";
var range2 = ws.getRange("A1048576");
range2.values = [["A"]];
await context.sync();
First it will set the value for A1:A1048575, and set value for A1048576 separately.
Internal bug #7377474 created to track it (which is true).
And our public repo: https://github.com/OfficeDev/office-js. You can put your future issue here also. And my github profile: https://github.com/yuc014 for the prove.
Thanks for your report. :)

Related

What is the reason my code cannot be parsed

I am trying to parse data. But this error comes:
Error parsing response
TypeError: Cannot read properties of undefined (reading 'response')
var result:
{
multistatus: {
'$': { xmlns: 'DAV:', 'xmlns:C': 'urn:ietf:params:xml:ns:caldav' },
response: [ [Object], [Object] ]
}
}
Code:
var data = result['D:multistatus']['D:response'];
if(data) {
data.map((event) => {
var ics = event['D:propstat'][0]['D:prop'][0]['C:calendar-data'][0];
var jcalData = ICAL.parse(ics);
var vcalendar = new ical.Component(jcalData);
var vevent = vcalendar.getFirstSubcomponent('vevent');
reslist.push(vevent)
});
}
Error:
Error parsing response
TypeError: Cannot read properties of undefined (reading 'response')
(Error to the line var data ...)
i expected to parse the data on correctly. Afterwards the events get filtered again.
You data structure is this:
{
multistatus: {
'$': { xmlns: 'DAV:', 'xmlns:C': 'urn:ietf:params:xml:ns:caldav' },
response: [ [Object], [Object] ]
}
}
Which means you should use the actual property names multistatus and response and change this:
var data = result['D:multistatus']['D:response'];
to this:
var data = result['multistatus']['response'];
I don't know why you put the D: at the front of the property names. Those are not present in the actual property names you show and must be removed.
Also, you should not be using var any more. Use either let or const.
The error message you get:
Cannot read properties of undefined (reading 'response')
Comes because this first part:
var data = result['D:multistatus']
results in undefined (since the D:multistatus property does not exist) and then you try to reference the second property off undefined, with this:
var data = result['D:multistatus']['D:response'];
you get that error as undefined is not an object and thus gives you an error when you try to reference a property on it.

Node.JS - Trying to delete certain items from a DynamoDB table

I am trying to delete all records which have the attribute "code" from a DynamoDB table. Here my params:
var params = {
TableName: table,
Key:{
"email": "email",
},
ConditionExpression:"attribute_exists(code)",
};
This is the error:
{
"message": "The conditional request failed",
"code": "ConditionalCheckFailedException",
"time": "2021-11-12T09:01:04.205Z",
"requestId": "e1d74c46-86a0-4f14-8c62-186102f2aff3",
"statusCode": 400,
"retryable": false,
"retryDelay": 36.80819226584606
}
An example record looks like this:
email - first_name - last_name - hash - code - confirmed
e#icloud.com - Bob - Mann - $2b$10$5/x6BkCks6ndXSr/GRhLgOPk.ettTv3lYpglbZbGnM7FXPX5VRFCe - undefined - undefined
According to the documentation:
ConditionalCheckFailedException
Message: The conditional request failed.
You specified a condition that was evaluated to be false. For example, you might have tried to perform a conditional update on an item, but the actual value of the attribute did not match the expected value in the condition.
OK to retry? No
So the problem is with the ConditionExpression, the code attribute does not exist in some records or it exists with undefined value. try to change attribute_exists with attribute_type:
var params = {
TableName: table,
Key:{
"email": "email",
},
ConditionExpression:"attribute_type(code, S)",
};
The second parameter:
S — String
SS — String Set
N — Number
NS — Number Set
B — Binary
BS — Binary Set
BOOL — Boolean
NULL — Null
L — List
M — Map
read more on comparison and function on amazondynamodb.

Unable to fetch the specific element value using jsonpath node js library

I'm trying to fetch the value of element based on it's value in the complex JSON file.
Trying to fetch the value attribute (Which is 100) if the currency ='BRL' and the index will be subject to change so I just want to try with condition based.
I just tried below so far:
Script:
function test()
{
var result = jsonpath.query(payload,"$..client_balance[?(#.type == 'AVAILABLE')]");
console.log(result);
}
test();
Output:
[
{
amount: { currency: 'BRL', value: '100', skip: false },
type: 'AVAILABLE'
},
{
amount: { currency: 'USD', value: '10', skip: false },
type: 'AVAILABLE'
}
]
Now, I just wanna fetch the value attribute (Which is 100) if the currency code = 'BRL'. I tried to apply the [?(#.currency == 'BRL')]
in the tail of the path variable but it returned empty array.
can someone help me to solve this problem.
Updated:
Tried filter function to get the specific element value.
console.log(Object.values(payload).filter(element =>{
element.currency === 'BRL';
}));
Output:
[]
console.log(Object.values(payload).filter(element =>{
return element.amount.currency === 'BRL';
}));
I think this should work
This is a bit of a complex query, but it should get you what you're looking for.
Start with what you have, which returns the result set you posted:
$..client_balance[?(#.type == 'AVAILABLE')]
Add to this another filter which looks inside the amount field at the currency field for the comparison:
$..client_balance[?(#.type == 'AVAILABLE')][?(#.amount.currency === 'BRL')]
This should give just the one element:
[
{
amount: { currency: 'BRL', value: '100', skip: false },
type: 'AVAILABLE'
}
]
From here you want to get the value field, but to get there, you need the path to it, meaning you have to go through the amount and currency fields first.
$..client_balance[?(#.type == 'AVAILABLE')][?(#.amount.currency === 'BRL')].amount.currency.value
This should return
[
100
]
Please note that we are working on a specification for JSON Path. If this library chooses to adhere to it once published, the === will need to change to a == as this is what we've decided to support.

Conditional filtering against a nested object in MongoDB

I am having a problem searching for a key of a nested object.
I have search criteria object that may or may not have certain fields I'd like to search on.
The way I'm solving this is to use conditional statements to append to a "match criteria" object that gets passed to the aggregate $match operator. it works well until I need to match to something inside a nested object.
Here is a sample document structure
{
name: string,
dates: {
actived: Date,
suspended: Date
},
address : [{
street: string,
city: string,
state: string,
zip: string
}]
};
My criteria object is populated thru a UI and passed a JSON that looks similar to this:
{
"name": "",
"state": ""
}
And although I can explicitly use "dates.suspended" without issue -
when I try to append address.state to my search match criteria - I get an error.
module.exports.search = function( criteria, callback )
let matchCriteria = {
"name": criteria.name,
"dates.suspended": null
};
if ( criteria.state !== '' ) {
// *** PROBLEM HAPPENS HERE *** //
matchCriteria.address.state = criteria.state;
}
User.aggregate([
{ "$match": matchCriteria },
{ "$addFields": {...} },
{ "$project": {...} }
], callback );
}
I get the error:
TypeError: Cannot set property 'state' of undefined
I understand that I'm specifying 'address.state' when 'address' doesn't exist yet - but I am unclear what my syntax would be surely it woulnd't be matchCriteria['address.state'] or "matchCriteria.address.state"
Is there a better way to do conditional filtering?
For search in Nested Object, You have to use unwind
A query that help you :
//For testing declare criteria as const
let criteria = {name : 'name', 'state' : 'state'};
let addressMatch = {};
let matchCriteria = {
"name": criteria.name,
"dates.suspended": null
};
if ( criteria.state) {
addressMatch = { 'address.state' : criteria.state };
}
db.getCollection('user').aggregate([{
$match :matchCriteria,
},{$unwind:'$address'},
{$match : addressMatch}
])
Firstly check for address, and then access the property as shown:
if(matchCriteria['address']) {
matchCriteria['address']['state'] = criteria['state'];
}
else {
//otherwise
}
This should fix it:
matchCriteria['address.state'] = criteria.state;

Excel Javascript API - Check for merge cells

I would like to query Excel for a range of cells and know whether there are merged cells within that range. I see that there is an API for merging cells and an API for unmerging cells. Does anyone know if it is possible to just check for merge cells?
Currently we don't have an API to query the state of merged cells.
Please log a feature request on UserVoice and we will take it into account for future API planning.
-Philip, Developer on the Office Extensibility team
Docs: https://learn.microsoft.com/en-us/javascript/api/excel/excel.range?view=excel-js-preview#getMergedAreasOrNullObject__
Note: This is still a WIP for me, would need a "isNull" check and I haven't adapted this for production code, but this should be a good starting point. I recommend examine the mergedAreas object if you need further details.
Here is how I did it:
async function Get_Merged_Areas_Arr_Of_Objs(context, ws) { //test for Null
var mergedAreas = ws.getUsedRange(true).getMergedAreasOrNullObject();
mergedAreas.load(["areas"]);
await context.sync()
var Merged_Areas_Arr_Of_Objs = []
var arrlen = mergedAreas.areas.items.length
for (var ai = 0; ai < arrlen; ai += 1) {
var obj = mergedAreas.areas.items[ai]
var rng_obj = {}
rng_obj['worksheet'] = obj['address'].split("!")[0]
rng_obj['rowIndex'] = obj['rowIndex']
rng_obj['columnIndex'] = obj['columnIndex']
rng_obj['rowCount'] = obj['rowCount']
rng_obj['columnCount'] = obj['columnCount']
Merged_Areas_Arr_Of_Objs.push(rng_obj)
}
return Merged_Areas_Arr_Of_Objs
}
var Merged_Areas_Arr_Of_Objs = await Get_Merged_Areas_Arr_Of_Objs(context,ws)
console.log('Merged_Areas_Arr_Of_Objs:')
console.log(Merged_Areas_Arr_Of_Objs)
[object Object],[object Object],[object Object],[object Object]
[
0: {
[functions]: ,
__proto__: { },
columnCount: 1,
columnIndex: 0,
rowCount: 3,
rowIndex: 1,
Symbol()_7.z1gk27bjwa1: undefined,
Symbol(nodejs.util.inspect.custom)_j.z1gk27bjwa1: undefined,
worksheet: "Sheet3"
},
1: { },
2: { },
3: { },
length: 4
]

Resources