So I have like kind of a homemade economy thing and when I added a working command and when it works it picks a random number and stuff but when it adds the number to the old currency it's adding like for ex 123+123 = 123123 when it supposed to be 246 I don't know how to fix this I tried everything and nothing has worked for me
if (message.content.toLowerCase().startsWith(prefixS.prefix + 'work')) {
const inventoryS = await inventory.findOne({ userID: message.author.id, guildID: message.guild.id });
if (inventoryS.item1 === 'true') {
const payment = Math.floor(Math.random() * 125) + 25;
inventoryS.currency += payment
inventoryS.save()
message.channel.send({ embeds: [new Discord.MessageEmbed().setTitle('After a long day of work your balance is').setDescription(`__Your balance__\n > Money: ${inventoryS.currency}`).setColor('BROWN')] })
}
}
Both of them must be Numbers to do addition, otherwise it will add as strings
inventoryS.currency = parseInt(inventoryS.currency) + parseInt(payment)
it is possible that your inventoryS.currency is a string value
let a = '123' //a string
let b = 123 //an integer
a += b
console.log(a) //logs 123123
you will need to parse it to an integer before adding
let a = '123'
let b = 123
a = parseInt(a) + b
console.log(a)
more references here
Related
I am trying to create a pop up to warn a user they must update a part in inventory if the part date is more than 90 days old. The date on the sheet (Cell Q5) is autofilled from another sheet, but that shouldn't matter. The value for the cell on the spreadsheet is 9/2/2021. I've tried many things, but currently I am getting the value for Q5 showing up as NaN .
function CheckInvDate() {
var ss = SpreadsheetApp.getActive().getId();
var partsrange = Sheets.Spreadsheets.Values.get(ss, "BOM!A5:Q5");
var currentDate = new Date();
var parthist = new Date();
parthist.setDate(currentDate.getDate() -90);
for (var i = 0; i < partsrange.values.length; i++){
var name = partsrange.values [i][1]
var partdate = partsrange.values [i][16]
var parthisttime = new Date(parthist).getTime();
var partdatetime = new Date(partdate).getTime();
Logger.log("History " + parthisttime)
Logger.log("Current " + partdatetime)
SpreadsheetApp.flush()
// if (parthist > partdate == "TRUE") {
// SpreadsheetApp.getUi().alert('The price on '+ name + ' is out of date. Please update price and try again.')
// }
}
}
My last log was
[22-07-06 11:50:55:851 EDT] History 1649346655850
[22-07-06 11:50:55:853 EDT] Current NaN
I've seen a number of responses on Stack Overflow, but I can't understand them. They seem to refer to variables that I don't see in code, or commands I haven't seen before and I'm not sure if they are in date.
Try this:
function CheckInvDate() {
const ss = SpreadsheetApp.getActive();
const vs = Sheets.Spreadsheets.Values.get(ss.getId(), "BOM!A5:Q5").values;
let d = new Date();
d.setDate(d.getDate() - 90)
const dv = d.valueOf();
const oldthan5 = vs.map(r => {
if (new Date(r[16]).valueOf() < dv) {
return r;
}
}).filter(e => e);
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(`<textarea rows="12" cols="100">${JSON.stringify(oldthan5)}</textarea>`).setWidth(1000), "Older Than 90 Days");
}
This outputs a dialog with the rows older than 90 days
I went to try this on my script again after lunch, and for whatever reason I am no longer getting the NaN value. I made one change on the if statement to fix the logic, and now it is working correctly. Not sure what I did, but apparently the coding gods were unhappy with me before.
The only part I changed was
if (parthisttime > partdatetime) {
SpreadsheetApp.getUi().alert('The price on '+ name + ' is out of date. Please update price and try again.')
}
I would like it so that when one or more of the options in my checkboxlist has been ticked, the value of said option will then update the amount field.
I'm sort of cheating as I'm using the key value to be the price of the field which I would then like to update the amount field with.
This already works perfectly with the dropdown fields and this does calculate the amount field depending on what has been selected.
As I've had to make the checkboxlist jasonable, the way in which this returns the value is different.
Jobs model:
type_website:
label: Website Package
span: right
type: dropdown
placeholder: '-- Select Website Package --'
trigger:
action: show
condition: value[1]
field: type
type_add_pages:
label: 'Additional Pages'
span: right
type: dropdown
trigger:
action: show
condition: value[1]
field: type
type_addons_get:
label: 'Addons'
span: right
type: checkboxlist
trigger:
action: show
condition: value[1]
field: type
amount:
label: 'Total Amount'
span: left
type: text
readOnly: true
dependsOn:
- type_add_pages
- type_website
- type_addons_get
Jobs.php
protected $jsonable = [
'type_addons_get'
];
public function getTypeAddonsGetOptions()
{
return [
'30' => 'Blog',
'50' => 'Editable Website'
];
}
// Get the value for the amounts field
public function filterFields($fields, $context = null)
{
$typePages = $this->attributes['type_add_pages'];
$typeAddons = array_get($this->attributes, 'type_addons_get');
$typeWebsite = array_get($this->attributes, 'type_website');
return $fields->amount->value = $typeAddons + $typePages + $typeWebsite;
}
As a test, if I just return the following in Jobs.php:
return $fields->amount->value = $typeAddons;
I then get the following result:
Any help would be extremely helpful, thanks in advance!
I will be honest and admit I don't work with the back end forms very often. I actually generate front end systems for clients and myself. So I solved an issue like this with using javascript/jquery in the controller pages (create and update). This is what I think you are trying to do. Here is an example:
Backend in form where I have total price set to read only number input field:
<script>
$('#Form-field-Products-price').change(doThing);
$('#Form-field-Products-set_size').change(doThing);
$('#Form-field-Products-set_color').change(doThing);
$('#checkbox_Form-field-Products-add_ons_1').change(doThing);
$('#checkbox_Form-field-Products-add_ons_2').change(doThing);
$('#checkbox_Form-field-Products-add_ons_3').change(doThing);
function doThing(){
var x = $('#Form-field-Products-price').val();
var y = $('#Form-field-Products-set_color').val();
switch (y) {
case 'silver':
color = 0;
break;
case 'bronze':
color = ".50";
break;
case 'gold':
color = "1.00";
break;
default:
color = 0;
}
var z = $('#Form-field-Products-set_size').val();
switch (z) {
case 'fullset':
size = 0;
break;
case 'partialset':
size = "1.00";
break;
default:
size = 0;
}
if ($('#checkbox_Form-field-Products-add_ons_1').prop('checked') == true)
{
var a = "1.00";
} else
{
var a = 0;
}
if ($('#checkbox_Form-field-Products-add_ons_2').prop('checked') == true)
{
var b = "1.00";
} else
{
var b = 0;
}
if ($('#checkbox_Form-field-Products-add_ons_3').prop('checked') == true)
{
var c = "1.50";
} else
{
var c = 0;
}
$("#Form-field-Products-total_price").val(Number(x) + Number(color) + Number(a) + Number(b) + Number(c) - Number(size));
console.log( Number(x) + ' ' + Number(color) + ' ' + Number(a) + ' ' + Number(b) + ' ' + Number(c) + ' ' + Number(size) );
}
</script>
Here you can see that I am searching the document for these ID's then getting their value. Turning those values into numbers I then push them into the Total Price field.
Here is an adjusted price while filling out the form:
I'd presume this would be an easy solve but I've been unable to find a solution anywhere online.
I'm trying to send automated emails when I run a script. The problem is it will send one email for every row (multiple emails to the same person) instead of sending one email with every row/column included in that one email.
The second issue is I want to send to more than one recipient. In my sheet, I want to send the data in B2:F3 to the first email address and then I want to send B4:F5 to the second email provided.
Thank you for your help. - Jared
Here's my script:
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("sheet1"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:m8");
var data = dataRange.getValues();
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[0];
var city = rowData[11];
var dimension = rowData[1];
var product = rowData[2];
var tally = rowData[3];
var price = rowData[5];
var ship = rowData[5];
var message = city + '\n\n' + dimension + ' ' + product + ' ' + tally + ' ' + price + ' ' + ship;
var subject = 'PFP Lumber';
MailApp.sendEmail("emailaddress1#blank.com",
"PFP Lumber",
message);
}
}
From your shared sample sheet and script, there are some questions.
It seems that price and ship are rowData[5].
price and ship are rowData[4] and rowData[5], respectively?
It seems that rowData[11] is Phone.
Is this rowData[6]?
If price, ship and Phone are rowData[4], rowData[5] and rowData[6], respectively, you want to send the following emails.
Mail 1 :
mailaddress: emailaddress1#blank.com
message: Gulfport desc1 1 1 1 1, Gulfport desc2 2 2 2 2
Mail 2 :
mailaddress: emailaddress2#blank.com
message: Gulfport desc3 3 3 3 3, Gulfport desc4 4 4 4 4
If my understanding is correct, how about this modification? I think that there are several answers for your situation, so please think of this as one of them.
Modification points :
Retrieve email address and messages.
When new email address was NOT found at column A, the message is added.
When new email address was found at column A, the email is separated.
Modified script :
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("sheet1"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:m8");
var data = dataRange.getValues();
// Modified
var temp = [];
var emailAddress, dimension, product, tally, price, ship, city;
for (var i in data) {
[emailAddress, dimension, product, tally, price, ship, city] = data[i];
var message = city + '\n\n' + dimension + ' ' + product + ' ' + tally + ' ' + price + ' ' + ship;
if (emailAddress || !dimension) {
if (temp.length > 0) {
MailApp.sendEmail(temp[0], "PFP Lumber", temp.slice(1,temp.length).join("\n"));
var temp = [];
}
temp.push(emailAddress, message);
if (!dimension) break;
} else {
temp.push(message);
}
}
}
Note :
Several messages for one mail address is separated by \n.
Because I'm not sure the variables for each columns that you want to use, please modify them if the variables of my modified script is difference from you want.
In this modified script, after the rows that Dimension of column B is empty, I recognized that there are no emails you want to send.
If I misunderstand your question, I'm sorry.
Edit :
When you want to add a signature, how about this script?
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("sheet1"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:m8");
var data = dataRange.getValues();
var temp = [];
var emailAddress, dimension, product, tally, price, ship, city;
var signature = "\n---\nsample signature";
for (var i in data) {
[emailAddress, dimension, product, tally, price, ship, city] = data[i];
var message = city + '\n\n' + dimension + ' ' + product + ' ' + tally + ' ' + price + ' ' + ship;
if (emailAddress || !dimension) {
if (temp.length > 0) {
MailApp.sendEmail(temp[0], "PFP Lumber", temp.slice(1,temp.length).join("\n") + signature);
var temp = [];
}
temp.push(emailAddress, message);
if (!dimension) break;
} else {
temp.push(message);
}
}
}
My code is based on the example of google code:
https://developers.google.com/maps/articles/phpsqlinfo_v3
and was working fine.
I need to change a former 'gid' (Integer) field to 'id' (String) to get saved to the database and used to display a new labeled symbol on the map.
The strange thing is, that the url, that is build in the code to call the addrow.php file is OK. When I capture this string with alert(url), and I manually use this string, the new data is added to the database.
In my script, the call seems to fail (responseCode == 200 && data.length <=1), since no data is written to the database and the alert from the 'else-clause' is displayed as short pop-up.
Here's the code I use in my project (to save data from a form):
//save new marker to Postgis-database and add new markerwithlabel on the fly
function saveData(){
var gender = escape(document.getElementById("gender").value);
var hoehe = InZahl(document.getElementById("hoehe").value);
var breite = InZahl(document.getElementById("breite").value);
var id = escape(document.getElementById("id").value);
var vital = document.getElementById("vital").value;
var typ = document.getElementById("typ").value;
var ein_mehr = document.getElementById("ein_mehr").value;
var st_durchm = document.getElementById("st_durchm").value;
var frucht = document.getElementById("frucht").value;
var anmerk = document.getElementById("anmerk").value;
var latlng = marker.getPosition();
var url = "./mapdata/addrow.php?gender=" + gender +
"&hoehe=" + hoehe + "&lat=" + latlng.lat() + "&lng=" + latlng.lng() +
"&breite=" + breite + "&id=" + id + "&typ=" + typ + "&ein_mehr=" +ein_mehr + "&st_durchm=" + st_durchm +
"&frucht=" + frucht +
"&vital=" + vital + "&anmerk=" + anmerk;
downloadUrl(url, function (data, responseCode) {
if (responseCode == 200 && data.length <=1) {
infowindow.close();
marker.setDraggable(false);
marker.setIcon('./images/mm_purple.png');
marker.labelContent = id;
marker.setMap(map);
downloadUrl("./mapdata/getxml_get_last.php", function (data1) {
var xml = parseXml(data1);
var ms = xml.documentElement.getElementsByTagName("m");
var gid = ms[0].getAttribute("gid");
var html_n = "<div id='InfoWindow'><p style='font-weight:bold;'>" + id + "</p> \n\<p>Höhe:" + hoehe + " Breite: "+ breite +
"<br />\n\Typ: "+typ+" Stämme: "+ein_mehr+" St-Durchm: "+ st_durchm + "<br />\n\Vitalität: "+vital+" Fruchtbehang: "+frucht+
"<p/>\n\<p style='text-align:right;'><a href='sm_juniperus.php?operation=ssearch&ResetFilter=0&SearchField=gid&FilterType=%3D&FilterText="+ gid +
"' target='_blank'> Daten editieren </a></p></div>";
infowindow.setContent(html_n);
bindInfoWindow(marker, map, infowindow, html_n);
(function(i, marker, gid) {
var origIcon = marker.getIcon();
new LongPress(marker, 1000);
google.maps.event.addListener(marker, 'longpress', function(e) {
marker.setDraggable(true);
marker.setIcon(mmcross);
});
google.maps.event.addListener(marker, 'dragend', function(){
updatePosition(marker, gid);
marker.setIcon(origIcon);
});
})(i,marker,gid);
//add new marker to markerCluster-Array and to markerArray
markerCluster.addMarker(marker,false);
markerArray.push(marker);
i++;
}); // End add new marker
}
else {
alert("Your data couldn't be saved!");
}
}); // End downloadUrl
}; // END saveData()
As I said, my code worked fine, but after 3 evenings passed to solve this, I thought it would be time to ask for help.
If anybody has an idea, where the mistake lies, I would apreciate any hint.
Just to confirm, you're aware that you by doing
if (responseCode == 200 && data.length <=1) {
you are saying 'if the request is successful and the data it returns is only one character or below in length'? I am unsure if this is intended or not, because this way the code inside the if statement is only ran if the response is successful but contains only 1 or 0 characters.
I have created a table in Google Sheets and I want to send automatically that table (25 rows, 2 columns) every 5 days to a specific email.
I already know how to send email via script, basically you use MailApp.sendEmail.
function sendFuelcount() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
sheet.setActiveSheet(sheet.getSheets()[0]);
var column1 = sheet.getRange("D2:D25").getValue();
var column2 = sheet.getRange("A2:A25").getValue();
var data = Utilities.formatDate(new Date(), "GMT", "dd-MMM-yyyy")
var msg = ""+nome+" "+fuel+"\n"
MailApp.sendEmail("abcd#gmail.com", ""+data+"", msg, {
name: 'Auto Message'});
This is the code so far, but unfortunately, it only writes the first row of the two columns instead of the 25 x 2 values.
In email I get:
Column11 Column12
What I want in email body is:
Column11 Column12
Column21 Column22
Column31 Column32
Column41 Column42
Column51 Column52
Until Column 25,1 and Column 25,2 or copy of the Google Sheet table.
Hope I have made myself clear.
Thank you.
EDIT: The answer below does the trick for export all values but not in a organized way.
What I get in the email is this:
A,B,C,D,...,i
1,2,3,4,...,j
What I want is this:
A - 1
B - 2
C - 3
D - 4
i - j
Is there a way to do this? Meaning how to organize and show that in the email. Like a table.
I manage to do this:
function sendFuelcount() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
sheet.setActiveSheet(sheet.getSheets()[0]);
var nom0 = sheet.getRange("A1").getValue();
var fue0 = sheet.getRange("D1").getValue();
var line0 = nome0 + "......" + fuel0;
var nom1 = sheet.getRange("A2").getValue();
var fue1 = sheet.getRange("D2").getValue();
var line1 = nome1 + "......" + fuel1;
var nome2 = sheet.getRange("A3").getValue();
var fuel2 = sheet.getRange("D3").getValue();
var line2 = nome2 + "......" + fuel2;
var nom3 = sheet.getRange("A4").getValue();
var fue3 = sheet.getRange("D4").getValue();
var line3 = nome3 + "......" + fuel3;
var nom4 = sheet.getRange("A5").getValue();
var fue4 = sheet.getRange("D5").getValue();
var line4 = nome4 + "......" + fuel4;
var nom5 = sheet.getRange("A6").getValue();
var fue5 = sheet.getRange("D6").getValue();
var line5 = nome5 + "......" + fuel5;
var data = Utilities.formatDate(new Date(), "GMT", "dd-MMM-yyyy") //define a data
var msg = ""+line0+"\n"+line1+"\n"+line2+"\n"+line3+"\n"+line4+"\n"+line5+" \n EMAIL GERADO AUTOMATICAMENTE"
MailApp.sendEmail("abcd#abcd.com", ""+data+"", msg, {
name: 'Auto Message'});
}
I manage to get this results:
Ba......(L)
eda......21
Alf......601
Arcs......95
Aamar......16
Canco......45
EMAIL GERADO AUTOMATICAMENTE
It's better but not what I want. What I want (or to create a table):
Ba.......(L)
eda......21
Alf......601
Arcs.....95
Aamar....16
Canco....45
EMAIL GERADO AUTOMATICAMENTE
This is what I want but the code I think is overly complicated, and I have to repeat that 25 times. I don't know how to properly use the For. But I think it can be useful here.
Thank you.
You will have to use getValues() instead of getValue()