- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将发布下面的全部代码。
我正在使用 Google 脚本,从不断变化的工作表中提取一些数据,执行计算,然后重新填充该工作表。
数据正在被调用到应用程序中,因此我试图尽快进行计算(因此,如果有人可以告诉我更有效的方法来执行此操作,那也会很有帮助)。
当我尝试调用 invoicePrice()
函数或 tiers()
函数时,出现 TypeError:找不到函数。
function invoicePrice() {
// define row to do calculations on
var AVals = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange("A1:A1000").getValues();
var ALast = AVals.filter(String).length;
// Set order No. here
var orderNoPrev = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast - 1, 3).getValue();
var orderNo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 3).setValue(orderNoPrev + 1);
var total = 0;
// invoicePrice the total number of items
var itemRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 4, 1, 14).getValues()[0];
// set the values of the constants on the Products page
var priceRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Products").getRange("F1:F1000").getValues();
var pLast = priceRange.filter(String).length;
var pGrab = priceRange.splice(0,pLast);
var invoicePrice = 0;
// set weight of case values
var weightRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Products").getRange("V1:V1000").getValues();
var wLast = weightRange.filter(String).length;
var wGrab = weightRange.splice(0,wLast);
for (var i = 0, len = 13; i <= len; i++) {
// SUBTOTAL THE ORDER AMOUNT
var orderAmount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, i + 4).getValue();
total += orderAmount;
// SET/KG PRICES
var perKGInvoice = pGrab[i + 1].map(Number);
// SET WEIGHTS
var weights = wGrab[i + 1].map(Number);
// SET CASE PRICE
var casePrice = perKGInvoice * weights;
// SUM OF PRODUCT PRICE * ORDER AMOUNT * WEIGHT OF CASE
invoicePrice += orderAmount * perKGInvoice * weights;
}
Logger.log(invoicePrice, ALast, pGrab, wGrab);
return [invoicePrice, ALast, pGrab, wGrab];
}
function tiers() {
var invoicePriceCall = invoicePrice();
var invoicePrice = invoicePriceCall[0];
var ALast = invoicePriceCall[1];
var beefDiscount = 0;
var sfDiscount = 0;
var currentTier = ""
// Set the invoice order value required ($ amount)
var tier1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(3, 3).getValue();
var tier2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(4, 3).getValue();
var tier3 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(5, 3).getValue();
var tier4 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(6, 3).getValue();
var tier5 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(7, 3).getValue();
var minNotmet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(10, 3).getValue();
// Set the discount tier levels for beef (% discount)
var tier1BeefDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(3, 4).getValue();
var tier2BeefDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(4, 4).getValue();
var tier3BeefDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(5, 4).getValue();
var tier4BeefDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(6, 4).getValue();
var tier5BeefDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(7, 4).getValue();
var tier1SfDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(3, 5).getValue();
var tier2SfDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(4, 5).getValue();
var tier3SfDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(5, 5).getValue();
var tier4SfDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(6, 5).getValue();
var tier5SfDiscount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DiscountGrid").getRange(7, 5).getValue();
if (invoicePrice < tier1) {
beefDiscount = tier1BeefDiscount;
sfDiscount = tier1SfDiscount;
currentTier = "Minimum Not Met"
}
else if (invoicePrice < tier2) {
beefDiscount = tier1BeefDiscount;
sfDiscount = tier1SfDiscount;
currentTier = "Tier 1"
}
else if (invoicePrice < tier3) {
beefDiscount = tier2BeefDiscount;
sfDiscount = tier2SfDiscount;
currentTier = "Tier 2"
}
else if (invoicePrice < tier4) {
beefDiscount = tier3BeefDiscount;
sfDiscount = tier3SfDiscount;
currentTier = "Tier 3";
}
else if (invoicePrice < tier5) {
beefDiscount = tier4BeefDiscount;
sfDiscount = tier4SfDiscount;
currentTier = "Tier 4";
}
else {
beefDiscount = tier5BeefDiscount;
sfDiscount = tier5SfDiscount;
currentTier = "Tier 5";
}
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 20).setValue(beefDiscount);
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 21).setValue(sfDiscount);
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 22).setValue(currentTier);
return [beefDiscount, sfDiscount, tier1];
}
function calcsOnColumns2() {
// call price range and weight from previous function
var invoicePriceCall = invoicePrice();
var invoicePrice = invoicePriceCall[0];
var ALast = invoicePriceCall[1];
var priceRange = invoicePriceCall[2];
var weightRange = invoicePriceCall[3];
// call tiers function
var tiers = tiers();
var beefDiscount = tiers[0];
var sfDiscount = tiers[1];
var tier1 = tiers[2];
// set sums to 0
var beefSum = 0;
var sfSum = 0
for (var i = 0, len = 13; i <= len; i++) {
// SUBTOTAL THE ORDER AMOUNT
var orderAmount = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, i + 4).getValue();
// SET/KG PRICES
var perKGInvoice = priceRange[i + 1].map(Number);
// SET WEIGHTS
var weights = weightRange[i + 1].map(Number);
// SET CASE PRICE
var casePrice = perKGInvoice * weights;
// Split up seafood and beef with if statement:
if (i < 9) {
// set discount case price
var discountCaseBeef = perKGInvoice - (perKGInvoice * beefDiscount);
// set the total price of the discounted cases in the order (ie, order price * discount)
var beefCaseOrder = discountCaseBeef * orderAmount * weights;
beefSum += beefCaseOrder;
// Nice and Formatted sheet
var casePrice = perKGInvoice * weights;
if (orderAmount) { SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, i + 32).setValue(orderAmount + " cases @" + discountCaseBeef.toFixed(2) + "/kg = ~$" + beefCaseOrder.toFixed(2)); }
}
else {
var discountCaseSF = perKGInvoice - (perKGInvoice * sfDiscount);
// set the total price of the discounted cases in the order (ie, order price * discount)
var sfCaseOrder = discountCaseSF * orderAmount * weights;
sfSum += sfCaseOrder;
// Nice and Formatted sheet
var casePrice = perKGInvoice * weights;
if (orderAmount) { SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, i + 32).setValue(orderAmount + " cases @" + discountCaseSF.toFixed(2) + "/kg = ~$" + sfCaseOrder.toFixed(2)); }
}
if (i == len) {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 24).setValue(beefSum);
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 25).setValue(sfSum);
// if statement to go here if min order size not met
var sumOfSums = beefSum + sfSum;
// swap out 75 with referenced value
if (sumOfSums > tier1) { SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 27).setValue(sumOfSums) }
// swap out phrase with changable phrase
else { SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 27).setValue("Minimum order size not met") }
var totalDiscount = invoicePrice - sumOfSums
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 29).setValue(totalDiscount);
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SubtotalDisplay").getRange(ALast, 30).setValue(invoicePrice);
}
}
}
最佳答案
问题
正确声明的函数 (invoicePrice
) 在从另一个函数 (calcsOnColumns2
) 调用时是未定义
。
重现步骤
假设您有三个名为 A
、B
、C
的函数,然后调用 B
会导致错误:
function A() {
var A = 0;
return [A];
}
function C() {
var a = A();
var A = a[0];
}
function B() {
A();
C();
}
您可能注意到,这就是您的函数的归结 - 行为是由于提升:
B
调用A
,它返回一个第一个元素为0
的Array
;C
调用函数A
并覆盖A
以输出A
;<相反,在第二步中,A
被声明为等于 a
的第一个元素,然后才调用 A
。由于 a
通过调用 A
获取其值,因此 A
将是 undefined
,结果是: [undefined]()
->“不是函数”
优化
getRange()
、getValue()
)放入循环中 - 输入/输出总是很慢,因此通常最好将所有内容加载到内存中并在那里处理数据。if...else
内声明两个同名的变量,将其移至外部范围)。我对您的脚本进行了一些优化,请看一下(请在使用前检查,因为我们没有示例数据,所以无法测试它)。您还可以做更多事情(特别是关于 calcsOnColumns2 中的循环),但这应该是一个开始:
/**
* [Your decription here]
* @returns {Number[]}
*/
function invoicePrice() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var subtotalDisplaySheet = ss.getSheetByName('SubtotalDisplay');
// define row to do calculations on
var AVals = subtotalDisplaySheet.getRange("A1:A1000").getValues();
var ALast = AVals.filter(String).length;
// Set order No. here
var orderNoPrev = subtotalDisplaySheet.getRange(ALast - 1, 3).getValue();
var orderNo = subtotalDisplaySheet.getRange(ALast, 3).setValue(orderNoPrev + 1);
// invoicePrice the total number of items
var itemRange = subtotalDisplaySheet.getRange(ALast, 4, 1, 14).getValues()[0];
// set the values of the constants on the Products page
var productsSheet = ss.getSheetByName("Products");
var priceRange = productsSheet.getRange("F1:F1000").getValues();
var pLast = priceRange.filter(String).length;
var pGrab = priceRange.splice(0, pLast);
var outputInvoicePrice = 0;
var weightRange = productsSheet.getRange("V1:V1000").getValues();
var wLast = weightRange.filter(String).length;
var wGrab = weightRange.splice(0, wLast);
var orderAmounts = subtotalDisplaySheet.getRange(Alast, 17).getValues();
var total = 0;
for (var i = 0, len = 13; i <= len; i++) {
var nextI = i + 1;
var orderAmount = orderAmounts[0][i + 4];
total += orderAmount;
var perKGInvoice = pGrab[nextI].map(Number);
var weights = wGrab[nextI].map(Number);
var casePrice = perKGInvoice * weights;
outputInvoicePrice += orderAmount * casePrice;
}
Logger.log(outputInvoicePrice, ALast, pGrab, wGrab);
return [outputInvoicePrice, ALast, pGrab, wGrab];
}
/**
* Gets values from 5 rows in
* a column starting from row 3
* @param {Sheet} sheet
* @param {Number} column
* @returns {*[]}
*/
function getGridValues(sheet, column) {
var range = sheet.getRange(3, column, 5, 1);
return range
.getValues()
.map(function (row) {
return row[0];
});
}
/**
* [Your decription here]
* @returns {Number[]}
*/
function tiers() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var discountGridSheet = ss.getSheetByName("DiscountGrid");
var invoicePriceCall = invoicePrice();
var outputInvoicePrice = invoicePriceCall[0];
var ALast = invoicePriceCall[1];
var beefDiscount = 0;
var sfDiscount = 0;
var currentTier = "";
var tierValues = getGridValues(discountGridSheet, 3);
var tier1 = tierValues[0];
var tier2 = tierValues[1];
var tier3 = tierValues[2];
var tier4 = tierValues[3];
var tier5 = tierValues[4];
var minNotmet = discountGridSheet.getRange(10, 3).getValue();
var tierBeefDiscountValues = getGridValues(discountGridSheet, 4);
var tier1BeefDiscount = tierBeefDiscountValues[0];
var tier2BeefDiscount = tierBeefDiscountValues[1];
var tier3BeefDiscount = tierBeefDiscountValues[2];
var tier4BeefDiscount = tierBeefDiscountValues[3];
var tier5BeefDiscount = tierBeefDiscountValues[4];
var tierSfDiscountValues = getGridValues(discountGridSheet, 5);
var tier1SfDiscount = tierSfDiscountValues[0];
var tier2SfDiscount = tierSfDiscountValues[1];
var tier3SfDiscount = tierSfDiscountValues[2];
var tier4SfDiscount = tierSfDiscountValues[3];
var tier5SfDiscount = tierSfDiscountValues[4];
if (outputInvoicePrice < tier1) {
beefDiscount = tier1BeefDiscount;
sfDiscount = tier1SfDiscount;
currentTier = "Minimum Not Met";
}
else if (outputInvoicePrice < tier2) {
beefDiscount = tier1BeefDiscount;
sfDiscount = tier1SfDiscount;
currentTier = "Tier 1";
}
else if (outputInvoicePrice < tier3) {
beefDiscount = tier2BeefDiscount;
sfDiscount = tier2SfDiscount;
currentTier = "Tier 2";
}
else if (outputInvoicePrice < tier4) {
beefDiscount = tier3BeefDiscount;
sfDiscount = tier3SfDiscount;
currentTier = "Tier 3";
}
else if (outputInvoicePrice < tier5) {
beefDiscount = tier4BeefDiscount;
sfDiscount = tier4SfDiscount;
currentTier = "Tier 4";
}
else {
beefDiscount = tier5BeefDiscount;
sfDiscount = tier5SfDiscount;
currentTier = "Tier 5";
}
var subtotalDisplaySheet = ss.getSheetByName("SubtotalDisplay");
var subtotalDisplayRange = subtotalDisplaySheet.getRange(ALast, 20, 3, 1);
subtotalDisplayRange.setValues([
[beefDiscount],
[sfDiscount],
[currentTier]
]);
return [beefDiscount, sfDiscount, tier1];
}
/**
* Foramts amount string
* @param {Number} amount
* @returns {Function}
*/
function formatAmount(amount) {
return function (discount, caseOrder) {
return amount + " cases @" + discount.toFixed(2) + "/kg = ~$" + caseOrder.toFixed(2);
};
}
/**
* Counts sum by discount, amount and weights
* @param {Number} amount
* @param {Number} weights
* @returns {Number}
*/
function countSum(amount, weights) {
return function (discount) {
return discount * amount * weights;
};
}
/**
* Counts discount case per Kg
* @param {Number} perKG
* @returns {Number}
*/
function countDiscountCase(perKG) {
return function (discount) {
return perKG - (perKG * discount);
};
}
/**
* [Your decription here]
*/
function calcsOnColumns2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var subtotalDisplaySheet = ss.getSheetByName("SubtotalDisplay");
var invoicePriceCall = invoicePrice();
var outputInvoicePrice = invoicePriceCall[0];
var ALast = invoicePriceCall[1];
var priceRange = invoicePriceCall[2];
var weightRange = invoicePriceCall[3];
var tiers = tiers();
var beefDiscount = tiers[0];
var sfDiscount = tiers[1];
var tier1 = tiers[2];
var beefSum = 0;
var sfSum = 0;
var orderAmounts = subtotalDisplaySheet.getRange(ALast, 17).getValues();
for (var i = 0, len = 13; i <= len; i++) {
var orderAmount = orderAmounts[0][i + 4];
var nextI = i + 1;
var perKGInvoice = priceRange[nextI].map(Number);
var weights = weightRange[nextI].map(Number);
var casePrice = perKGInvoice * weights;
var subtotalRange = subtotalDisplaySheet.getRange(ALast, i + 32);
var formatAmountOrder = formatAmount(orderAmount);
var countDisountSum = countSum(orderAmount, weights);
var countPerKGCase = countDiscountCase(perKGInvoice);
// Split up seafood and beef with if statement:
if (i < 9) {
var discountCaseBeef = countPerKGCase(beefDiscount);
var beefCaseOrder = countDisountSum(discountCaseBeef);
beefSum += beefCaseOrder;
} else {
var discountCaseSF = countPerKGCase(sfDiscount);
var sfCaseOrder = countDisountSum(discountCaseSF);
sfSum += sfCaseOrder;
}
if (orderAmount) {
subtotalRange.setValue(
i < 9 ?
formatAmountOrder(discountCaseBeef, beefCaseOrder) :
formatAmountOrder(discountCaseSF, sfCaseOrder)
);
}
if (i == len) {
subtotalDisplaySheet.getRange(ALast, 24).setValue(beefSum);
subtotalDisplaySheet.getRange(ALast, 25).setValue(sfSum);
// if statement to go here if min order size not met
var subtotalRange = subtotalDisplaySheet.getRange(ALast, 27);
var sumOfSums = beefSum + sfSum;
subtotalRange.setValue(sumOfSums > tier1 ? "Minimum order size not met" : sumOfSums);
var totalDiscount = outputInvoicePrice - sumOfSums;
subtotalDisplaySheet.getRange(ALast, 29).setValue(totalDiscount);
subtotalDisplaySheet.getRange(ALast, 30).setValue(outputInvoicePrice);
}
}
}
注释
i++
是一个例子,但是函数式风格将说即使这样也是有问题的)。invoicePrice
是 undefined
这么说更多)。引用文献
关于javascript - Google 脚本 - 在另一个函数中调用函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60255114/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!