我表示只在单元格中写数字的列。例如:
我写了15022019
,然后转到数字格式并选择date
。因此,数字将转换为15/02/2019
。
但是当我写一个数字时,我不需要每次都更改日期格式。我需要它。所以我找到了这个脚本:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var column = sheet.getRange("D3:D31");
column.setNumberFormat("dd/mm/yyy");
有效。但是错误地将数字更改为日期格式。如果我写14022019
,它会转换为24/12/40290
,而不是14/02/2019
(我的期望)。
为什么?
只是以手动方式正确转换。我的位置是巴西。
有人可以说我在做什么错吗?
编辑1:
每次我用日期填充一个单元格时,我都需要它自动转换为日期。我的范围日期将始终为D3:D31
。我尝试修改下面的行:
function convertnumbertodate(crange){
// establish spreadsheet credentials
var ss1=SpreadsheetApp.getActive();
var sh1=ss1.getActiveSheet();
// get the range so that rows and columns can be calculated
var rg1=sh1.getRange(crange);
然后我将(crange)
替换为D3:D31
,以尝试使转换自动为最新日期。看下面:
function convertnumbertodate(crange){
// establish spreadsheet credentials
var ss1=SpreadsheetApp.getActive();
var sh1=ss1.getActiveSheet();
// get the range so that rows and columns can be calculated
var rg1=sh1.getRange(D3:D31);
但是当我运行函数convertnumbertodate
时,它报告错误。
您能帮我如何使其自动转换为日期吗?
谢谢
编辑2:
只是做了你所做的:
function convertnumbertodate() {
// establish spreadsheet credentials
var editedCell;
var sh1=ss1.getActiveSheet();
// get the range so that rows and columns can be calculated
var rg1=sh1.getRange(D3:D31);
// get number of columns
var numColumns = rg1.getNumColumns();
// if more than one column chosen, stop the process.
if (numColumns !=1){
//Logger.log("DEBUG: Number of columns in range = "+numColumns); // DEBUG
var message = "Too Many Columns; one column only";
return message;
}
etc.
我删除了crange
,并将范围D3:D31
还使其运行OnEdit
:var editedCell;
但是当我跑步时,它说在var rg1=sh1.getRange(D3:D31);
行中有一个错误
答案 0 :(得分:0)
问题
OP在未格式化的单元格中输入14022019。将单元格格式化为日期时,返回的值为40290 December 24;返回值为40290。 OP预计日期为2019年2月14日。
解决方案
-1:将单元格的格式设置为输入之前的日期。
-2:输入带分隔符的数字 ,例如14/02/2019或14-02-2019
说明
当OP在未格式化的单元格中键入“ 14022019”时,他们打算将输入内容视为日期(2019年2月14日)。但是,Google会根据内容看重内容;没有关于日期/时间的推论。因此,当单元格随后被格式化为日期时,原始值将转换为日期,并且该单元格显示40290 12月24日。
原因是Google时间纪元始于1899年12月31日00:00:00(与1970年1月1日开始的Javascript 使用的Unix时间纪元相反。 00:00:00)。其次,Google以天为单位测量日期时间(与Unix Epoch相比,以秒为单位)。
(大致是 )这就是Google如何将14,022,019转换为40290年12月24日。
注意#1:还有一个复杂之处。
表格和Apps脚本处理“日期”的方式非常不同。
参考/信用:Rubén
注释#2:我对Google Epoch的引用是(https://webapps.stackexchange.com/a/108119/196152)
注释3:大致date/time conversions are based on每小时3,600秒,每天86,400秒,每年31,556,926秒和每年365.24天。
更新-2019年2月20日
OP非常正确地问,“那么我该如何转换现有的单元格呢?”
进行转换的代码非常简单: -将数字转换为字符串 -将字符串切成天,月和年的组成部分 -使用组件创建新日期 -用日期更新单元格
要转换的范围是一个潜在问题。范围是多少,范围是否总是相同大小,等等?以下代码使用户可以选择一个范围的界面。然后可以转换范围。可以说,这个元素不是必需的,但是确实提供了一种更为灵活(甚至不是优雅的)解决方案。
Code.gs
function onOpen(){
SpreadsheetApp.getUi()
.createMenu("Date Convert")
.addItem("Convert", "selRange")
.addToUi();
}
function selRange()//run this to get everything started. A dialog will be displayed that instructs you to select a range.
{
var output=HtmlService.createHtmlOutputFromFile('pickRange').setWidth(300).setHeight(200).setTitle('Convert to dates');
SpreadsheetApp.getUi().showModelessDialog(output, 'Convert Numbers to Dates');
}
function selCurRng()
{
var sso=SpreadsheetApp.getActive();
var sh0=sso.getActiveSheet();
var rg0=sh0.getActiveRange();
var rng0A1=rg0.getA1Notation();
rg0.setBackground('#FFC300');
return rng0A1;
}
function clrRange(range)
{
var sso=SpreadsheetApp.getActive();
var sh0=sso.getActiveSheet();
var rg0=sh0.getRange(range);
rg0.setBackground('#ffffff');
}
function convertnumbertodate(crange){
// establish spreadsheet credentials
var ss1=SpreadsheetApp.getActive();
var sh1=ss1.getActiveSheet();
// get the range so that rows and columns can be calculated
var rg1=sh1.getRange(crange);
// get number of columns
var numColumns = rg1.getNumColumns();
// if more than one column chosen, stop the process.
if (numColumns !=1){
//Logger.log("DEBUG: Number of columns in range = "+numColumns); // DEBUG
var message = "Too Many Columns; one column only";
return message;
}
// get the first row and the number of rows
var rowqty = 1;
var rownum = rg1.getRow();
// Logger.log("DEBUG: first row = "+rownum);//DEBUG
var rowqty = rg1.getNumRows();
// Logger.log("DEBUG: Number of rows = "+rowqty); //DEBUG
// get the values - different syntax for a single cell vs range
if (rowqty !=1){
// Multiple cells - uset GetValues
var rangevalues = rg1.getValues();
}
else {
// single cell, use getValue
var rangevalues = rg1.getValue();
}
//Logger.log("DEBUG: Values = "+rangevalues); //DEBUG
// create array for temporary storage
var newvalues = [];
// loop through the values
for (var i=0; i< rowqty; i++){
// different treatment for single cell value
if (i!=0 && rowqty !=1){
// multiple cells
var nstring = rangevalues[i].toString();
}
else {
// single value cell
var nstring = rangevalues.toString();
}
Logger.log("DEBUG: Value of the string is = "+nstring); //DEBUG
// slice the string in day, month and year
var daystring = nstring.slice(0, 2);
var monthstring = nstring.slice(2, 4);
var yearstring = nstring.slice(4, 8);
//calculate the date
var pubdate = new Date(yearstring, monthstring - 1, daystring);
//Logger.log("DEBUG: the date is "+pubdate); //DEBUG
// push the value onto the aray
newvalues.push([pubdate]);
}
// set the value(s)
if (rowqty !=1){
// Multiple cells - uset GetValues
rg1.setValues(newvalues)
}
else {
// single cell, use getValue
rg1.setValue(newvalues);
}
//rg1.setValues(newvalues);
var message = "Update complete";
rg1.setBackground('#ffffff');
return message;
}
pickRange.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var grange='';
function selectRange()
{
$('#btn1').prop('disabled',true);
$('#btn2').prop('disabled',false);
google.script.run
.withSuccessHandler(setResponse)
.selCurRng();
}
function setResponse(r)
{
grange=r;
var msg='Selected range: ' + r+". Ready to convert";
$('#instr').css('display','none');
$('#rsp').text(msg);
}
function convert2date()
{
$('#btn1').prop('disabled',false);
$('#btn2').prop('disabled',false);
google.script.run
.withSuccessHandler(setResponse02)
.convertnumbertodate(grange);
}
function setResponse02(q)
{
qnumber=q;
var msg= q;
$('#instr').css('display','none');
$('#rsp').text(msg);
}
function clearAndClose()
{
google.script.run.clrRange(grange);
google.script.host.close();
}
console.log('My Code');
</script>
</head>
<body>
<div id="rsp"></div>
<div id="instr">Select range - <b>One column limit</b></div>
<br/>
<input type="button" id="btn1" value="1 - Select a range" onClick="selectRange();" />
<br />
<input type="button" id="btn3" value="2 - Convert numbers to dates" onClick="convert2date();" />
<br />
<input type="button" id="btn2" value="close" onClick="clearAndClose();"; disabled="true" />
</body>
</html>
信用
// Prompt user for range in .gs function, pass array to html script and re-focus on the HTML dialog
// Cooper的信用答案-https://stackoverflow.com/a/45427670/1330560
添加
如果知道输入伪日期的范围并且该范围没有变化,则简化了管理伪代码的代码
function onEdit(e) {
// establish spreadsheet credentials
var ss1 = SpreadsheetApp.getActive();
var sh1 = ss1.getActiveSheet();
// get the onEdit parameters
var debug_e = {
authMode: e.authMode,
range: e.range.getA1Notation(),
source: e.source.getId(),
user: e.user,
value: e.value,
oldValue: e.oldValue
};
//Logger.log("AuthMode: "+debug_e.authMode+"\n, Range: "+debug_e.range+"\n, source: "+debug_e.source+"\n, user: "+debug_e.user+"\n, value: "+debug_e.value+"\n, old value: "+debug_e.oldValue);
// Note the range for data entry is known and fixed.
// it is "D3:D31"
// Target range for converting numbers to dates
// set the column
var column = 4; // column D
// get the first row and the number of rows
var rowqty = 29;
var rowfirst = 3;
var rowlast = 31;
//Logger.log("DEBUG: first row = "+rowfirst+", last row = "+rowlast+", number of rows = "+rowqty);//DEBUG
// get detail of the edited cell
var editColumn = e.range.getColumn();
var editRow = e.range.getRow();
//Logger.log("DEBUG: edited column = "+editColumn+", edited row "+editRow);//DEBUG
//test if the edited cell falls into the target range
if (editColumn == 4 && editRow >= rowfirst && editRow <= rowlast) {
// the edit was in the target range
var nstring = e.value.toString();
//Logger.log("DEBUG: Value of the string is = "+nstring); //DEBUG
// slice the string in day, month and year
var daystring = nstring.slice(0, 2);
var monthstring = nstring.slice(2, 4);
var yearstring = nstring.slice(4, 8);
//calculate the date
var pubdate = new Date(yearstring, monthstring - 1, daystring);
//Logger.log("DEBUG: the date is "+pubdate); //DEBUG
e.range.setValue(pubdate)
} else {
//Logger.log("DEBUG: Nothing to see here; this cell not in the target range");//DEBUG
}
}