0

我有一個簡單的腳本設置,使用基於腳本的VLookup基於Google表單條目發送電子郵件以獲取聯繫人電子郵件。在某些情況下,Google表單會將輸入到表單字段的較長數字轉換爲科學記數法。我一直使用的解決方法是在數字前輸入一個撇號 - 出於某種原因,這使得單元格格式化爲明文。我想找到一個不需要額外步驟的解決方案。如何防止Google表單將表單輸入轉換爲科學記數法格式

該工作表具有帶單一字段eGC的表單。 eGCs字段可以包含任意字母和數字的組合,可以是多行字符串。該腳本通過電子郵件正文中的eGCs字段條目向用戶onFormSubmit發送電子郵件。當我嘗試提交一個只有數字的非常長的字符串並將表單條目變量轉換爲科學記數法時,會出現問題。

我需要用戶在eGCs字段中輸入的任何信息都顯示爲正確,因爲它們都在回覆1表單和發送電子郵件的正文中輸入。下面是代碼:

function onFormSubmit(e) { 

    var eGCs = e.values[1]; 
    var email = Session.getActiveUser().getEmail(); 

//Replace the Google Sheets formatted line breaks with HTML line breaks so they display properly in the email: 
    eGCs = eGCs.replace(/\n/g, '<br>'); 

//Send the email: 
    var subject = "This is only a test"; 
    var body = eGCs; 
    MailApp.sendEmail(email, subject, body, {htmlBody: body}) 
    return 
    } 

如果我提交

6110523527643880 

...到形式,數量更改爲科學記數法格式,並顯示爲6.11052E+15都在紙張上,並在電子郵件中已發送。如果我提交多行字符串,如:

6110523527643880 
6110523527643880 
6110523527643880 

...那麼腳本工作正常,(因爲谷歌不認爲這是一個數更多的可能)的形式字段項不能轉換。我需要它與輸入的內容完全一樣,無論表單條目是單行還是多行。

這是我的example sheet/script/form。它應該是公開的,所以請隨時測試它。

+0

它是表單還是電子表格正在轉換它?您是否嘗試將格式更改爲電子表格? –

+0

嗨斯賓塞 - 我不確定。這個人正在處理的問題是相同的,如果這有幫助:https://productforums.google.com/forum/m/#!msg/docs/dMIAKVtuKW0/4P6w5KzeIu0J 我的懷疑是,在這個過程中的某個地方谷歌將單元格更改爲「自動」格式而不是「純文本」。我在電子表格中將整列設置爲「純文本」格式,但這似乎並不重要。我試着用這些評論中的某個人提出的腳本,但仍然沒有運氣。 – cwg83

+0

我創建了一個虛擬工作表,以便您可以親自看到它的實際運行情況。將它添加到頂部的原始帖子中。 – cwg83

回答

2

以形式形式迴應(與Spreadsheets相反)將響應存儲爲字符串。您的觸發器函數可以從表單獲取響應以獲取響應者輸入的字符串。

function onFormSubmit(e) { 
    // Get response sheet. First version works only in contained script, 
    // second works even in stand-alone scripts. 
// var sheet = SpreadsheetApp.getActiveSheet(); 
    var sheet = e.range.getSheet(); 

    // Get URL of associated form & open it 
    var formUrl = sheet.getParent().getFormUrl(); 
    var form = FormApp.openByUrl(formUrl); 

    // Get response matching the timestamp in this event 
    var timestamp = new Date(e.namedValues.Timestamp); 
    // NOTE: There is a race condition between the updates in Forms and Sheets. 
    // Sometimes (often!) the Spreadsheet Form Submission trigger function is invoked 
    // before the Forms database has completed persisting the new Responses. As 
    // a result, we might get no results when asking for the most recent response. 
    // To work around that, we will wait and try again. 
    var timeToGiveUp = 0; 
    do { 
    if (timeToGiveUp > 0) Utilities.sleep(1000); // sleep 1s on subsequent tries 
    timeToGiveUp++; 
    var responses = form.getResponses(timestamp); 
    } while (responses.length == 0 && (timeToGiveUp < 3)); 
    Logger.log("time to give up "+timeToGiveUp); 
    var response = responses[0]; // assume just one response matches timestamp 
    var itemResponses = response.getItemResponses(); 
    var eGCsItemNumber = 1; // Indicates where the question appears in the form 
    var eGCs = itemResponses[eGCsItemNumber-1].getResponse().toString(); 

    // You now have exactly what the respondent typed, as a string. 
    // It can be used as-is in an email, for example. 
    var body = "The user entered: "+eGCs; 
    MailApp.sendEmail(
    Session.getActiveUser().getEmail(), 
    "This is only a test", 
    body 
    ); 

    // To preserve the value in the spreadsheet, we must 
    // force it to remain a string by prepending a tick (') 
    var eGCsCol = 2; 
    e.range.offset(0,eGCsCol-1,1,1).setValue("'"+eGCs); 
} 

注WRT 競爭條件評論:這是在這方面需要的代碼的實際工作是一條線:

var responses = form.getResponses(timestamp); 

雖然玩這個,我發現我是經常收到一個例外,如同在回答下面的答案一樣...

找不到方法getResponses(object)

事實證明,這隻發生在函數被表單提交事件觸發時,而不是從模擬事件的編輯器/調試器運行時發生。這意味着,在短時間內,我們要處理的響應不會被getResponses()的調用返回。

由於共享文檔的實現方式,對於任何更改,都會有一個傳播延遲 ......這是將資產的一個視圖更改爲傳播到所有其他視圖所需的時間。

在這種情況下,我們的觸發器功能以電子表格事件啓動,然後打開窗體視圖並嘗試讀取之前該視圖包含它們的最新響應。

一個簡單的解決方法是在sleep()的一段時間內允許傳播完成。

Utilities.sleep(5000); // 5s pause 
var responses = form.getResponses(timestamp); 

簡單,是 - 但效率低下,因爲即使我們不需要,我們也會等待。第二個問題是確定足夠長的時間......如果明天改變了會怎樣?

只有在第一次不成功時,選擇的解決方法纔會重試獲取響應。它只會在重試時等待。而且它不會永遠等待 - 通過timeToGiveUp應用的限制條件。 (我們可以添加在循環後成功額外的檢查,但由於下面的語句將通過一個異常,如果我們透過時限吹,我們就可以讓它做骯髒的工作。)

var timeToGiveUp = 0; 
do { 
    if (timeToGiveUp > 0) Utilities.sleep(1000); // sleep 1s on subsequent tries 
    timeToGiveUp++; 
    var responses = form.getResponses(timestamp); 
} while (responses.length == 0 && (timeToGiveUp < 3)); 

不止一行代碼,但更強大。

+0

感謝您繼續爲此解決方案,Mogsdad。我會盡力與您的代碼一起執行並報告。 – cwg83

+0

我收到了失敗摘要: 6/17/15 3:27 PM \t onFormSubmit \t找不到方法getResponses(object) - 我在頂部添加了我們的代碼,並將其結合到我的問題的底部,以便您可以看到我嘗試過。 – cwg83

+0

在這種情況下,itemResponses [2]應該是itemResponses [1],因爲eGCs列現在位於簡化表的B列中? – cwg83

1

我假設eGCs是對號碼的迴應。

e.values [2]將始終以字符串形式返回(在本例中爲「6.15312E + 16」),因此,在最後2次之後,所有內容都會丟失,因此無法將其轉換爲原始數字。即使您轉換它,最好的你可以得到的是「61531200000000000」

相反,你可以從電子表格中提取值。 在你onFormSubmit()函數的開頭添加以下代碼:

var ss = SpreadsheetApp.getActiveSpreadsheet(); 
var sheet = ss.getSheetByName("Form Responses 1"); 
var eGCs = sheet.getRange(sheet.getLastRow(), 2, 1, 1).getValue(); 
try { 
    eGCs = eGCs.toFixed(); 
} catch (e) { 
    Logger.log(eGCs); 
} 

EGCS現在將恢復爲完整的電話號碼,如果它是一個數字,否則將返回爲文本。

如果你想在電子表格時有新的迴應提交添加到您的代碼正確的格式:

sheet.getRange(sheet.getLastRow(), 2, 1, 1).setNumberFormat("000"); 

這將通過形式加入新行轉換到正確的格式。這不會影響電子表格中的實際值,只會影響格式化的方式。

+0

謝謝你的建議 - 我今天會嘗試這個,並報告回來。 – cwg83

+0

嗨阿什金 - 我能夠讓你的代碼工作(左邊有一個時間戳列,所以我不得不改變getLastRow(),2,1,1)getLastRow(),3,1,1)。該號碼在電子郵件中保留其格式,但由於某種原因該表未被轉換。我會在這部分工作並回復你。 – cwg83

+0

不幸的是,這並不適用於我的目的,因爲表單上的eGCs字段有時需要輸入多行數字,並且在這種情況下表現奇怪。我感謝你的幫助,因爲你比以前更接近我,但仍然不能按我的需要工作。 – cwg83

相關問題