I have watched a few videos and read as many web pages about how to debug my Google Sheets Macro. Oddly, I can't get this ridiculously simple macro to work. It just takes the values in column A and sorts them to send duplicate values to the end. When I try to debug the macro using step into, the steps don't seem to actually do anything until I execute the last statement. I see the same problem with the debugger with an even simpler macro that does work. Nothing happens until I step into the last step. BTW, I have written and debugged much more complicated Excel VBA scripts with no problems like I am having with Google scripts. I am trying to migrate to Google sheets due to Excel being beyond bloatware.
function EliminateDuplicates() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1:A20').activate()
.sort({column: 1, ascending: true});
spreadsheet.getRange('B2').activate();
spreadsheet.getCurrentCell().setFormula('=A2=A1');
spreadsheet.getRange('B2:B20').activate();
spreadsheet.getRange('B2').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
spreadsheet.getRange('B1').activate();
spreadsheet.getCurrentCell().setValue('FALSE');
spreadsheet.getRange('B1:B20').activate();
spreadsheet.getRange('B1:B20').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
spreadsheet.getRange('A1:B20').activate()
.sort({column: 2, ascending: true});
};
Related
I have a word file with approximately 750 fields which link to an Excel file (all to single cells, mostly not the same cell, always the same file), e.g.:
{ LINK Excel.SheetMacroEnabled.12 C:\\Dir1\\Dir1\\ExcelFile.xlsm Daten!Z1S1 \t \* MERGEFORMAT }
Updating the fields (CRTL+A -> F9) right after restarting Word is fairly quick. But if Word wasn't restarted it sometimes takes 10-20 minutes. On some PCs even restarting doesn't help.
When I checked the Task-Manger I saw multiple Excel-Instances could it be the Word open and closes the file for each field, even they all are linked to the same file. Is there a way to force Word to keep the file open?
I played around with the following VBA code with different variations, but so far I had no luck. This is the code I'm trying to get to work (going through all stories) and updating the fields:
Application.ScreenUpdating = False
ThisDocument.StoryRanges(i).Fields.Update
Selection.Fields.Update
I also tried to go through each field individually (which is undesirable since it means I have to build my own progress bar), but it doesn't resolve the performance issue:
Application.ScreenUpdating = False
ThisDocument.StoryRanges(i).Fields(j).Update
Selection.Fields.Update
DoEvents
Is there a way to prevent the low performance, or at least a way to further troubleshoot the problem?
Please Note: I also posted two other questions within this context:
VBA (Word): force user form to update in real time
How to show the progress of the “Fields.Update”-Method in VBA (Word)
Within a SQL Server 2017 Integration Services project, using the CozyRoc REST Connection Manager, I'm trying to use their JavaScript Task to Delete a Sheet in one Google Spreadsheet then copy the same-named Sheet from another Spreadsheet into that first spreadsheet using "CopyTo", then rename the copied sheet to remove the "Copy of . . ." portion of the title.
Sheet 1 is called "CompanyInfo". It has 7 Sheets, one of which is called "Daily Report".
Sheet 2 is called "Daily Report" which has only one sheet called 'Daily Report".
The overall task is simply to automate the process from within SSIS of overwriting the "Daily Report" sheet of the "Company Info" spreadsheet with the "Daily Report" sheet from the "Daily Report" spreadsheet. This is simple enough to do manually from Google Sheets, but it needs to be automated through SSIS.
Looking at the API, this will probably involve deleting the original "Daily Report" sheet from "Company Info," copying the Daily Report sheet from the "Daily Report" spreadsheet into a new tab in the "Company Info" spreadsheet, and then renaming that sheet to remove the "copy of " portion. Three simple BatchUpdate commands is my guess. But everywhere I look all I see are complicated updates to individual sheets, not batch updates.
I've contacted Cdata Software, but their SSIS GoogleSheet task doesn't do a "Copyto". That would make things simple.
I've tried desperately to get some guidance from CozyRoc, but generally all I'm told is to go look at the API reference for Sheet Operations, and that I need to write a web request, which I don't understand how to do.
As a start, I've googled all over for a simple complete little full piece of sample JavaScript code that specifies a Google Spreadsheet ID, a Google Sheet ID, and then deletes the specified sheet from within a web request. All I find anywhere are the little snippets from the API reference, and that's not helping me write the full script.
To be clear, For a number of reasons, I can't do this directly from within Google Sheets using an app script.
I totally get it that this is wrong:
task.run = function () {
var connection
variables = this.variables;
var SheetID = 1145890987;
var SpreadsheetID = "1r0tsxZ_nKT7EGG5qU6_6JPJ3dLOsZfF8pmdfsdgfagdahjI"
if (this.parameters.RestConnection.value) {
connection = this.connections[this.parameters.RestConnection.value].acquire();
connection.connect();
}
else {
connection = new RestConnection();
}
{
"requests"; [
{
"deleteSheet": {
"sheetId": SheetID
}
}
]
}
I expect the "Daily Report" sheet of the "Company info" spreadsheet to be overwritten by the "Daily Report" sheet of the "Daily Report" spreadsheet whenever I run the SSIS project called "Update Daily Report."
How do I solve this problem?
As it turns out, this was quite a process.
I ended up creating three basic CozyRoc Javascript tasks within SSIS referencing the API, each task containing just a very simple, short piece of code.
One step that copies the single Google Sheet into the Larger Google Sheet using "copyTo". The result is a sheet in the larger Google Spreadsheet called "Copy of . . ."
A second step that deletes the original Sheet from the larger Google Spreadsheet.
A third step that renames the new "Copy of" in the larger Spreadsheet to the original name.
Basically, the problems I had were simply that the API documentation has no decent real simple, clear examples of any of the three of these functions.
I knew how to construct the Body and URL strings for these three functions, but had a great deal of difficulty with the syntax. It was unclear in the documentation where brackets, braces, and quotation marks were needed in all three of the steps, particularly when you're using SSIS variables for the SpreadsheetId and SheetID. It took me over a period of DAYS to get this all working, when a few better examples of the Batchupdatate and copyTo functions would have helped.
I add rows to a Google Sheet via the API. For this, I use C# Google.API.Sheets.v4 NuGet package. I pretty much calculate the cells where I want to write in myself.
My problem is that when I reach the end of the worksheet, I don't know this in my application. There doesn't seem to be an error or anything. Data is just lost!
When I use my sheet without the API I would notice and just press this button:
I want to either add 1 row before writing one row in my application or recognize that the end of the worksheet is reached.
The code looks pretty much like the update code provided here:
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update
I use the spreadsheets.values.update functionality and write into a bottom row that doesn't yet exist
So again in short: I need the "more rows at bottom" functionality somehow in my application
Bonus Question: I lost some data because of this problem. Any ideas on how to recover it?
I found a sattisfying workaround. Instead of using the spreadsheets.values.update functionality I use the spreadsheets.values.append functionality as shown here.
It is important to set it to InsertDataOptionEnum.OVERWRITE to mimic the behaviour or you'll end up having each new cell in a separate row.
OLD ( uses .Update() )
SpreadsheetsResource.ValuesResource.UpdateRequest request = sheetsService.Spreadsheets.Values.Update(valueRange, spreadsheetId, range);
request.ValueInputOption = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.USERENTERED;
NEW ( uses .Append() )
//use AppendRequest instead of UpdateRequest to avoid lost lines on end of sheet
SpreadsheetsResource.ValuesResource.AppendRequest request = sheetsService.Spreadsheets.Values.Append(valueRange, spreadsheetId, range);
request.ValueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.USERENTERED;
request.InsertDataOption = SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum.OVERWRITE; //overwrite when writing cells or it will be new line per cell
In my google spreadsheet file I have many custom function, that perform requests to my server and download some data. I need to automatically export it to PDF and then send on particular email.
I wrote like this:
function sendPDF() {
var pdf = DriveApp.getFileById(SpreadsheetApp.getActive().getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'MyPDF.pdf',content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail("example#email.com", "PDF test", "test", {attachments:[attach]});
}
And add trigger on time, that will execute this function every hour. The problem is, that with one spreadsheet I get PDF without downloaded data, and with another spreadsheet I get We're sorry, a server error occurred. Please wait a bit and try again. (line 44, file "Code") error.
How can I force google spreadsheet to wait until data will be downloaded and after download send me final PDF?
Sadly, without the needed reputation I cannot comment above.
Why not having this as a separate function like you have now and just call the function in your main function that fetches the url and downloads the data.
You can even write the downloaded data on a separate spreadsheet and insert an IF function that when cells are not empty execute the pdf script! After executing the script clear() and loop if necessary.
I need to move some code around in VS using a macro. The code between the [source][/source] tags needs to go inside the [destination][/destination] tags. It has to work throughout an entire solution. I thought this would be simple, but I can't find any way to capture the results of the first find. I've looked at many Find&Replace examples but haven't found any that apply to my situation. So as a starter:
DTE.Find.FindWhat = "[source].*[/source]"
DTE.Find.Target = vsFindTarget.vsFindTargetSolution
Dim results = DTE.Find.Execute //this doesn't actually do anything useful
DTE.FindReplace(vsFindAction.vsFindActionReplaceAll, "[destination].*[/destination], vsFindOptions.vsFindOptionsRegularExpression, results, vsFindTarget.vsFindTargetSolution)