I am completely a novice at this, and borrowed part of a script from a sample online.
I am working a stamp with a dialogue box prompting for the date, and defaulting to the current date if no response. I have gotten it to display the dialogue box and the default date. But, the results don't end up on the stamp. Could someone please assist on resolving the issues?
if(event.source.forReal && (event.source.stampName == "#2Nw2jMn7S5l9QIPW-WGOHB"))
{
var rgEmpty = /^\s*$/;
var cDate = null;
var cDfltDate = null;
if((event.value != null) && !rgEmpty.test(event.value) && util.scand("mmm dd yyyy",event.value))
cDfltDate = event.value;
else
cDfltDate = util.printd("mmm dd yyyy",new Date());
while((cDate==null) || rgEmpty.test(cDate) || (null == util.scand("mmm dd yyyy",cDate)))
{
cDate = app.response({cQuestion:"Please Enter the Date",
cTitle:"Stamp Date Entry",
cDefault:cDfltDate ,
cLabel:"Date:"
});
if((cDate==null) || rgEmpty.test(cDate) || (null == util.scand("mmm dd yyyy",cDate)))
{
app.alert("Please enter date as \"mmm dd yyyy\"\n\nEx: Apr 15 2020",1);
if(cDate != null)
cDfltDate = cDate;
}
}
}
Also, I would like to distribute the final stamp to my coworkers as a template rather than them creating the script. Can I share the stamp pdf, and have them create one off my template without them having to modify the script?
Thank you!
First take a look at the following; https://acrobatusers.com/tutorials/dynamic_stamp_secrets
1) You should have a separate pdf file, that is the stamp file. This file can then be distributed to your coworkers if they copy the stamp file in the correct location, to find out the correct location run following code;
app.getPath ("app", "stamps");
app.getPath ("user", "stamps");
2) This stamp file should contain "fields", these fields can be filled in by a script that is attached to the stamp file, so you only need to distribute the stamp file that includes the script.
3) In your script you don't have a statement event.value = ...; if this is linked to a field it will fill in the field with the inputted date or current date.
Hope this is a help.
Thank you! I was able to solve the issue with assistance on another thread. Here is the last post there:
IT WORKS!!!
The date is required in oder to be official, and this specific format is also required. So, I think the exit of simply clicking OK is good enough because it gives a default date automatically.
Last thing to test is that an end user can just copy it directly into the stamps folder and start using it. I will test that out this morning when someone is available and follow up.
Thank you for your help!
Here is the code that worked:
console.println("Stamping:" + event.source.StampName);
if(event.source.forReal && (event.source.stampName == "#StampTemplate"))
{
var rgEmpty = /^\s*$/;
var cDate = null;
var cDfltDate = null;
if((event.value != null) && !rgEmpty.test(event.value) && util.scand("mmm dd yyyy",event.value))
cDfltDate = event.value;
else
cDfltDate = util.printd("mmm dd yyyy",new Date());
while((cDate==null) || rgEmpty.test(cDate) || (null == util.scand("mmm dd yyyy",cDate)))
{
cDate = app.response({cQuestion:"Please enter date as \"mmm dd yyyy\"\n\nFor Example: Apr 15 2020",
cTitle:"Stamp Date Entry",
cDefault:cDfltDate ,
cLabel:"Date:"
});
if((cDate==null) || rgEmpty.test(cDate) || (null == util.scand("mmm dd yyyy",cDate)))
{
app.alert("Please enter date as \"mmm dd yyyy\"\n\nFor Example: Apr 15 2020",1)
}
else
event.value = cDate;
}
}
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 am having issues making this work. I want to insert todays date in colum 4 upon making checkbox true in colum 1. There are multiple rows. I am not seeing the error of my ways. Any suggestions would be appreciated.
Thanks,
function onEdit(e) {
var ss = e.source.getActiveSheet();
var date = new Date();
if (e.range.columnStart != 1 || e.value != "TRUE") return;
ss.getRange(e.range.rowStart,4).setValue(date);
}
Instead of:
E.value != "TRUE"
Simply use:
!e.value
And then instead of:
ss.getRange(e.range.rowStart,4).setValue(date)
You can simply use:
e.range.offset(0,3).setValue(date)
That allows you to eliminate the need for the ss variable as well.
Using the code below, the google sheet enters the Date in column 6 when a cell in column 1 is edited. It also includes the timestamp.
How can this code be altered so that just the date (day-month-year) is entered? This would allow searches by date on the sheet.
function onEdit(e) {
var sheetName = 'Cases Allocation'; //name of the sheet the script should work on
var colToWatch = 1
var colToStamp = 6 //timestamp in col A
if (e.range.columnStart !== 1 || e.source.getActiveSheet()
.getName() !== sheetName || e.value == '') return;
var writeVal = e.value !== "" ? new Date(),: '';
e.source.getActiveSheet()
.getRange(e.range.rowStart, colToStamp)
.setValue(writeVal);
}
You can try using Utilities.formatDate. This method formats date according to specification described in Java SE SimpleDateFormat class. You can visit the date and time patterns here. An example of usage is:
// This formats the date as Greenwich Mean Time in the format
// year-month-dateThour-minute-second.
var formattedDate = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'");
Logger.log(formattedDate);
Do take note that using Utilities.formatDate has the following effects as noted in this post:
Utilities.formatDate does not change the cell format; it converts
its content to text. If you are going to use the date value in
computations, you don't want it to be converted to text.
Utilities.formatDate requires one to specify a timezone. If you put
something like "GMT+1" and your country observes Daylight Saving
Time, you can expect hard-to-track bugs to come up a few months
later. With setNumberFormat, the date value remains consistent with
all other date values in the spreadsheet, governed by its timezone
setting.
To avoid these, you can also use setNumberFormat(numberFormat) to set the date or number format. The accepted format patterns are described in the Sheets API documentation. And an example usage is:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("B2");
// Always show 3 decimal points
cell.setNumberFormat("0.000");
Thanks all - tried format etc, but then just decided to add a column and split the date and time, with just the date going into a new column.
function onEdit(e) {
var sheetName = 'Cases Allocation'; //name of the sheet the script should work on
var colToWatch = 1
var colToStamp = 6 //timestamp in col A
if (e.range.columnStart !== 1 || e.source.getActiveSheet()
.getName() !== sheetName || e.value == '') return;
//var writeVal = e.value !== "" ? new Date(),: '';
e.source.getActiveSheet()
.getRange(e.range.rowStart, colToStamp)
.setValue(new Date(new Date().setHours(0,0,0,0))).setNumberFormat('MM/dd/yyyy');
}
The below code will save the date without time. You can change the format as required. The field remains a date which can be used as required.
setValue(new Date(new Date().setHours(0,0,0,0))).setNumberFormat('MM/dd/yyyy');
Please, I don't need no solution, just a few hints on how-tos. Anyhow, here is the problem I am tackeling with:
I have a file (bloomberg answer file) which is built as follows:
we have a header part (I am only interested in the
START-OF-FIELDS[...]END-OF-FIELDS; varying amount of fields!)
then there is the data part: START-OF-DATA[...]END-OF-DATA. Where each row: unique_id|some_val|some_val|EXCH_CODE|ID_BB_GLOBAL|NAME|SECURITY_TYP|TICKER\n
Shortened example file:
START-OF-FILE
RUNDATE=20150921
PROGRAMFLAG=oneshot
DATEFORMAT=yyyymmdd_sep
FIRMNAME=dl111111
FILETYPE=pc
REPLYFILENAME=r150921020044_20426_01_00
SECMASTER=yes
DERIVED=yes
CREDITRISK=yes
USERNUMBER=1111111
WS=0
SN=111111
CLOSINGVALUES=yes
SECID=BB_GLOBAL
PROGRAMNAME=getdata
START-OF-FIELDS
EXCH_CODE
ID_BB_GLOBAL
NAME
SECURITY_TYP
TICKER
END-OF-FIELDS
TIMESTARTED=Mon Sep 21 01:01:18 BST 2015
START-OF-DATA
BBG004C5BLW2|0|5|LABUAN INTL FIN|BBG004C5BLW2|1MDB GLOBAL INVESTMENTS|EURO-DOLLAR|OGIMK|
BBG000MGZ064|0|5|HK|BBG000MGZ064|361 DEGREES INTERNATIONAL|Common Stock|1361|
BBG000QVRHX9|0|5|AV|BBG000QVRHX9|3BG EMCORE CONVRT GLB-A|Open-End Fund|EMBDGCA|
BBG000BP52R2|0|5|US|BBG000BP52R2|3M CO|Common Stock|MMM|
BBG0068TPTD9|0|5|TRACE|BBG0068TPTD9|51JOB INC|US DOMESTIC|JOBS|
BBG0069D1BR3|0|5|NOT LISTED|BBG0069D1BR3|51JOB INC|EURO-DOLLAR|JOBS|
BBG000BJD1D4|0|5|US|BBG000BJD1D4|51JOB INC-ADR|ADR|JOBS|
BBG008CTTWK1|0|5|FRANKFURT|BBG008CTTWK1|AABAR INVESTMENTS PJSC|EURO MTN|AABAR|
BBG008D4J9S9|0|5|FRANKFURT|BBG008D4J9S9|AABAR INVESTMENTS PJSC|EURO MTN|AABAR|
BBG008B2BXH2|0|5|SIX|BBG008B2BXH2|AARGAUISCHE KANTONALBANK|DOMESTIC|KBAARG|
BBG0016WJL30|0|5|LX|BBG0016WJL30|AB-AMERICAN INCOME PT-ATEURH|Open-End Fund|ABAATEH|
BBG006F3D598|0|5|BH|BBG006F3D598|ABBEY CAPITAL DAILY FUTURE-B|Fund of Funds|ABBDFUB|
END-OF-DATA
TIMEFINISHED=Mon Sep 21 01:03:22 BST 2015
END-OF-FILE
And now my questions
How can I split this file into 2 flows (field_names; data_rows)?
My problem was:
The regex component only works on row level...
The tFileInputMSDelimited does bring me nowhere...
I don't want to start parsing the file by hand (tJava)... or do I have to?
Thanks for any hints in advance,
Marco
No need to java code, check out this very simple job:
Generally, the header have fixed row count, so we need only to play with rows numbers:
tFileInputDelimited1: header 11 and limit 5
tFileInputDelimited2: header 20 and footer 3
and it works fine, if you have a dynamic rows positions, try to find these positions, save them in variables then use this job based on variables. You can also refeer to my answer here.
I'd use tJavaFlex and some Java code. If you look at the actual code its not that hard to understand how it works even if you don't really know java.
Begin:
boolean header = false;
boolean data = false;
String headerData = "";
String line;
Main:
line = input_row.line;
if(line.equalsIgnoreCase("START-OF-FIELDS") ) { header = true; }
if(line.equalsIgnoreCase("END-OF-FIELDS") ) { header = false; }
if(line.equalsIgnoreCase("START-OF-DATA") ) { data = true; }
if(line.equalsIgnoreCase("END-OF-DATA") ) { data = false; }
if(header && !line.equalsIgnoreCase("START-OF-FIELDS")) {
headerData += line + "|";
}
if (data) {
if(line.equalsIgnoreCase("START-OF-DATA")) {
output_row.line = headerData.substring(0,headerData.length()-1); //remove the trailing delimiter.
} else {
output_row.line = line;
}
} else {
continue; //lets go to the next line.
}
End:
//if you want to handle the header separately:
globalMap.put("headerData",headerData);
Hope this helps.
The below class will push the logindate into the custom field. You can use a formula to convert it from date/time to date. Then setup a scheduler to run the apex to keep the last login date up to date.
public void ResetlastLogin_Update(List<User> oldUsers, List<User> newUsers) {
System.debug('ResetlastLogin_Update: entering trigger');
List<Id> idsToUpdate = new List<Id>();
for (integer i=0; i<newUsers.size(); i++) {
User newVals = newUsers[i];
User oldVals = oldUsers[i];
if (newVals.lastlogindate != oldVals.lastlogindate__c) {
idsToUpdate.add(newVals.Id);
}
}
System.debug('Ids to Update: ' + idsToUpdate.size());
if (idsToUpdate.size() > 0) {
List<User> usersToUpdate = [SELECT Id, lastlogindate, lastlogindate__c FROM User WHERE Id IN :idsToUpdate];
for (User u : usersToUpdate) {
if (u.lastlogindate__c == NULL ) {
u.lastlogindate__c = u.lastlogindate ;
}
}
update usersToUpdate;
}
System.debug('ResetlastLogin_Update_Update: exiting trigger');
}
Check https://salesforce.stackexchange.com/questions/9926/execute-an-action-run-a-trigger-every-time-a-user-logs-in-to-salesforce. The act of logging in doesn't count as update of user record (for example lastmodifieddate doesn't change) which means that workflows & formulas are out of the question too.
You'll have to use batch apex to query that data or maybe consume a login history report (via Analytics API)...
As for your question. To convert from DateTime to Date you can use date() or dateGMT().
DateTime dt = System.now();
Date d = dt.date();
System.debug(dt + ' -> ' + d);
System.assertEquals(System.today(), d);
2014-01-14 18:44:14 -> 2014-01-14 00:00:00