I have been using the getEditResponseUrl method for quite some time. However now in the list of over 400 entries some of the urls which are generated end up with a blank form instead of the previously added content. Any idea on solving this?
function linksmaken() {
var urlCol = 64; // kolom nr 64 begint met 1
var responses = form.getResponses();
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
Related
I am sending some values from a microcontroller to a flutter app in the form of Uint8List then I convert it to. When I send values individually, I have no issue at all. however, when I send 100 values together or any number of values continuously, I get some values correct and others divided in multiple lines. I will be providing a screenshot for the result because its hard to represent it with typing.
This is the code tor receiving:
Future<void> _onDataReceived( Uint8List data ) async {
var fixedList = new List<String>.filled(6, '', growable: true);
// var fixedList1 = <Uint8List>[];
var fixed1 = new List<int>.filled(7, 0, growable: true);
// fixedList1.add(data);
if (data.length >= 7) {
for (int k = 0; k < 7; k++) {
// int x=0;
fixed1[k] = data[k+1];
l++;
}
if (l > 6) {
for (int i = 0; i <= 5; i++) {
fixedList[i] = String.fromCharCode(fixed1[i]);
fixed1[i]=0;
}
l = 0;
fixed1.clear();
print(fixedList); //fixedList1.clear();
}
}
}
Anyone knows what is going on here?
I'm trying to create an audioworklet that loops a single instance of a sound to create a sort of sustain effect. No matter how many sections of the input I loop, I keep hearing a blip type skipping sound. How many calls to the processor is one instance?
To give you an idea, this is what I have so far:
constructor() {
super();
this.sound = [];
this.count = 20;
this.step = [0, 0];
}
process(inputs, outputs, parameters) {
if (inputs && inputs.length) {
for (var i = 0; i < inputs[0].length; i++) {
var input = inputs[0][i];
var output = outputs[0][i];
if (!this.sound[i]) {
this.sound[i] = [];
}
if (this.sound[i].length < this.count) {
this.sound[i].push([]);
for (var j = 0; j < input.length; j++) {
this.sound[i][this.sound[i].length - 1][j] = input[j];
}
} else if (this.sound[i]) {
var s = this.sound[i][this.step[i] % this.sound[i].length];
for (var j = 0; j < s.length; j++) {
output[j] = s[j];
}
this.step[i]++;
}
}
}
return true;
}
So the idea is that I capture the incoming input in an array of N length for each channel(in my case there are 2 channels). Then once that array is full, I cycle through that array to fill the output until the node is disabled.
Thanks for the fiddle. Very helpful.
I didn't look to see what was causing the clicks, but I took your example and modified it very slightly like so:
// #channels 2
// #duration 1.0
// #sampleRate 44100
var bufferSize = 4096;
let ctx = context;
let osc = ctx.createOscillator();
osc.start();
let myPCMProcessingNode = ctx.createScriptProcessor(bufferSize, 2, 2);
let _count = 1;
var sound = [];
var count = _count++;
console.log(count)
var hesitate = 0;
var step = [0, 0];
//Logic to pay attention to
myPCMProcessingNode.onaudioprocess = function(e) {
for(var i = 0; i<2; i++){
var input = e.inputBuffer.getChannelData(i);
var output = e.outputBuffer.getChannelData(i);
if (!sound[i]) {
sound[i] = [];
}
if (sound[i].length < count) {
sound[i].push([]);
for (var j = 0; j < input.length; j++) {
sound[i][sound[i].length - 1][j] = input[j];
}
} else if (sound[i]) {
var s = sound[i][step[i] % sound[i].length];
for (var j = 0; j < s.length; j++) {
output[j] = s[j];
}
step[i]++;
}
}
}
//To hear
osc.connect(myPCMProcessingNode).connect(ctx.destination);
I pasted this in the code window at https://hoch.github.io/canopy. Press the top left button (arrow) to the left of the code window, and you can see the rendered audio. You can see that the output (frequency is 10 instead of 440 to make it easier to see) is discontinuous. This causes the clicks you hear. You can also change the frequency to 100 and find discontinuities in the output.
I hope this is enough to help you figure out what's wrong with your buffering.
An alternative is to create an AudioBufferSourceNode with an AudioBuffer of the basic sample. You can set the AudioBufferSourceNode to loop the whole buffer. This doesn't solve the clicking problem, but it is somewhat simpler.
But this is a general problem of looping any buffer. Unless you arrange the last sample to be close to the first sample, you will hear clicks when you wrap around. You either need to grab chunks where the first and last samples are nearly the same, or modified the chunks so they ramp up at the beginning in some way and ramp down at the end in some way.
I am using sap.m.MultiInput. How to send that data to the SAP Backend?
I tried using a loop:
for(var i = 0; i < oLenght; i++) {
var oData = this.getView().byId("myMultiInputControl").getTokens()[i].getKey();
}
But oData is holding always a new value. How to hold the data?
you can use a delimiter for example ("/" character) between the keys of the multinput and send the data to the backend System :
if(oMultiInputElement.tokens.length > 1) {
var dataToSend = "";
for(var i = 0; i < oMultiInputElement.tokens.length; i++) {
dataToSend = oFilterData.tokens[i].key + "/" + dataToSend;
}
} else {
dataToSend = oMultiInputElement.tokens[0].key;
}
I have been playing around with this script for the last couple weeks. The goal of the script is to go through a reporting inbox, pull reporting data from email attachments, copy into a google spreadsheet, and then relabel the emails to remove them from the inbox to prevent accidental double copying reports.
The script functions in this order:
Look for new emails in the Inbox with attachments
Copy attachment data
Paste into Spreadsheet in the next open row
Relabel the email with "Report" instead of "Inbox" to move all reports into a reporting folder
I have successfully accomplished steps 1 - 3, but for the life of me, I can not get the relabeling to work. When I run debug in the Google Apps console, it doesn't come back with any errors. Pasted below is the excerpt from the script doing the relabeling:
for (var i = 0; i < myLabel.length; i++) {
labels = myLabel[i].getLabels();
for (var j = 0; j < labels.length; j++) {
labels[j].addLabel("test_2");
labels[j].removeLabel("Test");
}
}
Below is the full script I am running.
function getCSV() {
// Create variable that looks for Gmails in the main inbox
var myLabel = GmailApp.getUserLabelByName("test");
Logger.log("myLabel:",myLabel);
// Create variable that is filled with all threads within Inbox label
var threads = myLabel.getThreads();
Logger.log("threads:",threads);
// Retrieves all messages in the specified thread
var msgs = GmailApp.getMessagesForThreads(threads);
Logger.log("msgs:",msgs);
// Uses active sheet the script is implemented on
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
// Grabs CSV data from attachments and pastes into next available row in Spreadsheet
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var attachments = messages[j].getAttachments();
Logger.log("attachments:",attachments);
var csvData = Utilities.parseCsv(attachments[j].getDataAsString(), ",");
Logger.log(csvData);
for (var k = 1; k < csvData.length; k++) {
var dataPaste = sheet.appendRow(csvData[k]);
Logger.dataPaste;
}
}
}
// Removes Inbox Label and Adds Report Label
for (var i = 0; i < myLabel.length; i++) {
labels = myLabel[i].getLabels();
for (var j = 0; j < labels.length; j++) {
labels[j].addLabel("test_2");
labels[j].removeLabel("Test");
}
}
}
I ended up figuring this out. In addition, I added a section that can pull data if the CSVs are zipped.
function getCSV() {
// Associated Inbox label and Report Label with variables
var myInboxLabel = GmailApp.getUserLabelByName("Test");
var myReportLabel = GmailApp.getUserLabelByName("test_2");
// Create variable that is filled with all threads within Inbox label
var threads = myInboxLabel.getThreads();
Logger.log("threads:" + threads);
// Retrieves all messages in the specified thread
var msgs = GmailApp.getMessagesForThreads(threads);
Logger.log("msgs:" + msgs);
// Uses active sheet the script is implemented on
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
/* Script to pull data from CSV that is NOT zipped
// Grabs CSV data from attachments and pastes into next available row in Spreadsheet
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var attachments = messages[j].getAttachments();
Logger.log("attachments:" + attachments);
var csvData = Utilities.parseCsv(attachments[j].getDataAsString(), ",");
Logger.log("csvData:" + csvData);
for (var k = 1; k < csvData.length; k++) {
var dataPaste = sheet.appendRow(csvData[k]);
Logger.dataPaste;
}
}
}
*/
// Grabs CSV within a zip folder and pastes into next available row in Spreadsheet
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var attachments = messages[j].getAttachments();
var extracted = Utilities.unzip(attachments[j]);
var csvData = Utilities.parseCsv(extracted[j].getDataAsString(), ",");
Logger.log(csvData);
for (var k = 1; k < csvData.length; k++) {
var dataPaste = sheet.appendRow(csvData[k]);
Logger.dataPaste;
}
}
}
// Removes Inbox Label and Adds Report Label
for (var x in threads) {
var thread = threads[x];
thread.removeLabel(myInboxLabel);
thread.addLabel(myReportLabel);
}
}
Based on googleAPI documentation:
https://developers.google.com/chart/interactive/docs/gallery/columnchart?hl=en
As you can see in "labeling columns" section each column is labeled with a static value. I want to know if it is possible to label a column with a specific value resulting of the sum of all.
// Set chart options
var options = {
width: 400,
height: 300,
calc:????
};
Should i set this "calc" field with a specific function?
JSFIDDLE: Total Labeling Column
I can't figure out how can i customize a label with the sum values of each stacked column.
You can use getNumberOfRows(), getNumberOfColumns() and getValue() functions to calculate total and set that value instead of string total:
function drawChart() {
// Create the data table.
var data = new google.visualization.arrayToDataTable(array);
for (var i = 0; i < data.getNumberOfRows(); i++) {
var total = 0;
for (var j = 1; j < data.getNumberOfColumns() - 2; j++) {
// console.log(data.getValue(i, j));
total += data.getValue(i, j);
}
data.setValue(i, data.getNumberOfColumns() - 1, '' + total);
}
...
You will have to change or size of chart or size of fonts to get values properly displayed on columns. Labels are displayed correctly.
This is my answer.. i hope it helps someone with the same issue.
function getValueAt(column, dataTable, row) {
return dataTable.getFormattedValue(row, column);
}
function setLabelTotal(dataTable) {
//dataTable must have role: annotation
var SumOfRows = 0;
for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
SumOfRows = 0;
for (var col = 0; col < dataTable.getNumberOfColumns(); col++) {
if (dataTable.getColumnType(col) == 'number') {
SumOfRows += dataTable.getValue(row, col);
}
if(dataTable.getColumnRole(col) == 'annotation')
{dataTable.setValue(row, col, SumOfRows.toString());}
}
}
}
Notice that you must call these methods on main function (e.g. "drawChart").