We are building an Excel add-in by using a dialog. The dialog box will delivery a message to its parent/opener workbook. The function file will call a simple function as example:
const populateTable = (officeMessage)=>{
Excel.run(async context => {
const workbook = context.workbook;
const worksheets = workbook.worksheets;
const sheet = worksheets.add();
sheet.getCell(0,0).values = [[officeMessage]];
await context.sync();
}).then(()=>{
showDialogEvent.completed();
dialog.close();
}).catch(handleError);
}
Two workbook/excel desktop have been opened (Excel1 and Excel2). The dialog is opened in Excel1. However, if I focus another workbook(Excel2) before this function is triggered. Officejs API will create a new worksheet in Excel2 instead Excel1, and an error will be thrown as below:
{"description":"There was an internal error while processing the request.","name":"RichApi.Error","code":"GeneralException","traceMessages":[],"innerError":null,"debugInfo":{"code":"GeneralException","message":"There was an internal error while processing the request.","errorLocation":"WorksheetCollection.add","statement":"var add=worksheets.add();","surroundingStatements":["var workbook=context.workbook;","var worksheets=workbook.worksheets;","// >>>>>","var add=worksheets.add();","// <<<<<","var cell=add.getCell(...);","// Instantiate {cell}","cell.values=...;"],"fullStatements":["Please enable config.extendedErrorLogging to see full statements."]},"stack":"GeneralException: There was an internal error while processing the request.\n at Anonymous function (https://appsforoffice.microsoft.com/lib/1.1/hosted/excel-win32-16.01.js:24:286584)\n at Anonymous function (https://cdn.jsdelivr.net/npm/promise-polyfill#8/dist/polyfill.min.js:1:822)"}
Note: I tried to save the first workbook's Request Context in memory and pass it into Excel.run, but it doesn't work.
Is there any way to solve this problem?
Thanks #Ericl for your report.
This is a known issue, we are working on a new feature (3743479) to fix this issue, A uservoice request was created , you could also upvote this request.
Please listen to this user voice, we will keep posted once we release this feature
The workaround currently is to force to open another instance/process of Excel to solve this problem.
Related
I am using the Xero-node SDK to automatically create client invoices which works well.
At the end of the process, I would like to automatically email the client the invoice.
In the documentation it has the following example:
const xeroTenantId = 'YOUR_XERO_TENANT_ID';
const invoiceID = '00000000-0000-0000-0000-000000000000';
const requestEmpty: RequestEmpty = { };
try {
const response = await xero.accountingApi.emailInvoice(xeroTenantId, invoiceID, requestEmpty);
console.log(response.body || response.response.statusCode)
} catch (err) {
const error = JSON.stringify(err.response.body, null, 2)
console.log(`Status Code: ${err.response.statusCode} => ${error}`);
}
I have 2 questions:
The requestEmpty method does not work in javascript. Does anyone know the correct structure of requestEmpty?
I have used requestEmpty = { } but this throws an error => even though the system does actually send an email (probably a bug)
AND....
Is there a way for me to specify the email template that I would like the invoice to use (if I have specific templates setup in the web version)? Currently it seems to use the default Xero email template.
If you don't get an answer to your first query here, please can you raise it on the SDK page in Github and the Xero SDK team will look into this for you.
With regards to point 2, it is not possible to choose the email template when sending through the API, a basic template is used.
Not sure how the create channel and create role isn't working inside the following code, towards the bottom. (EDIT: Nothing is sent to the console and nothing happens regardng the code. It is like it is entirely ignored.) This is a snippet from code that User A challenges User B. User B is messaged, alerting them that a challenge has been issued to them via a Private Message. If the challenge is accepted, I want the bot to 1)Make a role specifically for User A and User B named "User A vs User B" 2) take User A and User B and put them both into that new role and 3) Make a battlefield named "User A vs User B" inside a specific category inside the server the bot is on.
I am unsure if the problem lies in how the bot is trying to make the role and channel in a sever while the bot is talking to the user in a private message instead of on the server. I thought putting the "server" variable as the server ID would help but it doesn't seem to do anything after the accept message.
// Awaits reply from user
if (message.channel.id === '541736552582086656') return target.send("Do you accept the challenge? Please reply with 'accept' or 'deny'.")
.then((newmsg) => {
newmsg.channel.awaitMessages(response => response.content, {
max: 1,
time: 150000,
errors: ['time'],
}).then((collected) => {
// Grabs the first (and only) message from the collection.
const reply = collected.first();
if (reply.content === 'accept'){
reply.channel.send(`You have ***accepted *** the challenge from ${challenger}. Please wait while your battlefield is made...`);
message.author.send(`${target} has accepted your challenge! Please wait while the channel is made for your brawl...`)
/// Problems start here
function createChannel(message){
var server = "SERVER ID";
var name = `${target} vs ${challenger}`;
message.guild.createRole({
role: {
name: `${target} vs ${challenger}`,
color: "#00fffa",
permissions: [] }
}).then(role => {
target.addRole(role, name)
challenger.addRole(role, name)
.catch(error => client.catch(error))
}).catch(error => client.catch(error))
server.createChannel(Name, name).then(
(channel) => {
channel.setParent("CATEGORY ID")
})
} // problems end here
} else if (reply.content === 'deny') {
reply.channel.send("You have ***denied *** the challenge.")
} else {
reply.channel.send("Your response wasn't valid.");
}
})
})
}
I have been wondering if I need to go about making the channel and role in a different way since it is trying to be made from a private message and not inside the server..
Thanks for any and all help! I also apologize if I'm using stack overflow too much for problems like this... You guys are great at helping me see different ways to do things and what I'm doing wrong, so I am learning, but I don't want to feel like I'm abusing it too much.
I think the problem is the fact that you create a function called createChannel with the code to create a rol and channel, but you never call said function.
You can either call the function after you've declared it or (which is in my opinion better) you can remove the following lines
function createChannel(message){
} // problems end here
I need to create/add a new File from Files Lib, then i need to set the name of the file with an unique ID and update other fieds. I can update the fields without any problems, but i couldn't find a way to create the file.
How can i possibly achieve the New => Create from template like in the image below
I've tried many ways but nothing fullfill my request.
1
this.web.lists.getByTitle('myFilesLib').items.add() => i get an error about the need to use SPFileCollection.Add()
2
this.web.getFolderByServerRelativeUrl(url).files.addTemplateFile => there is nothing for custom template
3
this.web.getFolderByServerRelativeUrl(url).files.add => i need to provide a file.
For JSOM, you can try this:
newFile = parentList.get_rootFolder().get_files().add(fileCreateInfo);
For CSOM:
var creationInformation = new ListItemCreationInformation();
Microsoft.SharePoint.Client.ListItem listItem = list.AddItem(creationInformation);
listItem.FieldValues["Foo"] = "Bar";
listItem.Update();
clientContext.ExecuteQuery();
Some wiki for this way: https://social.technet.microsoft.com/wiki/contents/articles/37575.sharepoint-online-working-with-files-inside-document-library-using-jsom.aspx
this.web.getFolderByServerRelativeUrl(url).files.addTemplateFile is used to add page, so it is not suitable for your scenario.
http://www.ktskumar.com/2016/08/pnp-js-core-create-new-page-sharepoint-library/
The PnP JS method requires a File DOM or BLOB object for uploading a file to the SharePoint. Based on the those, we will try two options to upload a file to the SharePoint Library or folder in a library:BLOB/FileAPI
http://www.ktskumar.com/2016/09/pnp-js-core-upload-file-sharepoint/
More reference for you from Microsoft:
https://msdn.microsoft.com/en-us/library/office/dn450841.aspx
This is a sample code to use when you want to upload an existing ContentType to your content library on SharePoint.
const templateUrl = '/sites/App/Template/Forms/Template/test.docx'
const name = 'test.docx'
const depositUrl = '/sites/App/Template'
const web = new Web('http://localhost:8080/sites/App'); // Proxy URL for Dev
web.getFileByServerRelativeUrl(templateUrl)
.getBuffer()
.then((templateData: ArrayBuffer) => {
web.getFolderByServerRelativeUrl(depositUrl).files.add(name, templateData));
});
There is an issue if you use SP-Rest-Proxy at the moment (file is corrupted on SharePoint) but it should be fix soon.
If you Deploy your app on SharePoint, it work as expected.
Related links:
https://github.com/pnp/pnpjs/issues/196#issuecomment-410908170
https://github.com/koltyakov/sp-rest-proxy/issues/61
i am using integrated document server 4.4.3 ubuntu based, bellow code is customized for my suitability, how can i form a url based on key
asc_docs_api.prototype.asc_customCallback = function(typeFile, bIsDownloadEvent)
{
var actionType = c_oAscAsyncAction.DownloadAs;
var options = {downloadType : DownloadType.Download };
this._downloadAs("save", typeFile, actionType, options, function(incomeObject){
if (null != incomeObject && "save" == incomeObject["type"]) {
//incomeObject["data"] will return key of the document instead of key, i need full url of the document with md5 and expires like below
//ex: http://cache/files/.....
});
};
thank you in advance
You are trying to get the link too early, the file is not yet available, the conversion process might not be completed.
This callback only means that the conversion task is created
But you can try using the function onDownloadAs (created for the integrators who are going to create external button downloadAs)
http://api.onlyoffice.com/editors/config/events#onDownloadAs
A link to the file will be sent to:
asc_docs_api.prototype.processSavedFile = function(url, downloadType)
How to create and display a "HeroCard" within the fulfill() function of LUIS action binding using node.js ? I am following the samples provided by the microsoft(https://github.com/Microsoft/BotBuilder-Samples/tree/master/Node/blog-LUISActionBinding)
Here is that how I tried to do this...
fulfill: function (parameters, callback) {
utilities.FilterFunction(parameters.x, parameters.y).then(function (matches){
utilities.CreateCard(session, matches).then(function(cards){
var reply = new builder.Message(session)
.attachmentLayout(builder.AttachmentLayout.carousel)
.attachments(cards);
callback(util.format(reply));
});
});
}
How can I use session value in the fulfill method?...without session "utilities.CreateCard" won't work...
Since session is not available in the action's fulfill method, we can make call to only to the utilities.FilterFunction and return the result via the callback. Now in our main js file, in the fulfillReplyHandler we get the actionModel which contains the result from utilities.FilterFunction.
Now we can create the "HeroCard" using the "session" that is accessible in the fulfillReplyHandler.