我非常抱歉我不得不问这个问题,主要是因为搜索谷歌总是给我指出错误的方向。此外,这本身不是一个编程问题。事实上,我想要一个涉及最少代码的答案。
图 1 显示了问题的初始阶段:
我拥有的是一个主电子表格(大约 5000 行),从中生成了许多部分副本,每个副本针对不同的销售员,以便他只能看到与他相关的行(例如,在图中,电子表格是分成两半。)
如何生成副本与我无关——导演的工作是手动或以其他方式完成。重要的是,每一行都有一个唯一的键(第一列),并且保证在所有电子表格中保留该键。所有电子表格的格式和布局也保持相同。每个电子表格都是一个不同的文件,所有这些文件都应作为 Google 表格在线存储。主电子表格会定期更新(同样,通过与我无关的外部过程),当发生这种情况时,主管开始准备部分副本。一旦准备好,它就会分享给销售人员。
图 2 显示了销售人员开始编辑部分电子表格时发生的情况。
例如,销售员 1 已将键 1 行中的“值 2”更改为“值 22”,销售员 2 已将键 4 行中的“值 12”更改为“值 19”。编辑值时,主电子表格应进行更新以反映更改。更新应该自动或半自动进行。另外,如果更新的单元格能够突出显示(例如使用颜色),这样导演就很容易看到发生了什么变化,那就太好了。
有没有什么机制可以用来实现这个工作流程?如果涉及一些脚本也没关系,只要它对电子表格的用户是透明的。我尝试过使用 Google Apps 脚本,但它更像是一个笑话,而不是一个解决方案:它速度慢且不可靠。无论如何,这是更新主电子表格中单元格的脚本:
// ID of the master spreadsheet
var masterSheetId = 'MASTER_SHEET_ID';
// The name of the tab in each shared sheet
var tabName = 'Sheet1';
// Function to sync updates from partial to master
function syncPartial1() {
syncRowsById(masterSheetId, tabName);
}
// Sync specific rows based on Column 1 (ID) and color the updated cells
function syncRowsById(masterSheetId, sheetName) {
var partialSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
// Get data from the partial sheet
var partialData = partialSheet.getDataRange().getValues();
var partialIds = partialData.map(row => row[0]); // Get all values from Column 1 (ID)
// Get data from the master sheet
var masterSpreadsheet = SpreadsheetApp.openById(masterSheetId);
var masterSheet = masterSpreadsheet.getSheetByName(sheetName);
var masterData = masterSheet.getDataRange().getValues(); // Get all data from master
var masterIds = masterData.map(row => row[0]); // Get all values from Column 1 (ID)
// Loop through partial data
for (var i = 0; i < partialData.length; i++) {
var partialRow = partialData[i];
var partialId = partialIds[0]; // ID from Column 1
// Check if the ID exists in the master sheet
var rowIndexInMaster = masterIds.indexOf(partialId);
if (rowIndexInMaster > -1) {
// Get the current row in the master sheet
var masterRow = masterData[rowIndexInMaster];
// Update the corresponding row in the master sheet and color changed cells
for (var j = 0; j < partialRow.length; j++) {
if (partialRow[j] !== masterRow[j]) { // If the cell value is different
// Update the cell
masterSheet.getRange(rowIndexInMaster + 1, j + 1).setValue(partialRow[j]);
// Color the updated cell (e.g., light yellow)
masterSheet.getRange(rowIndexInMaster + 1, j + 1).setBackground('#FFFF99');
}
}
}
}
}
我试图避免的是必须从那些电子表格(每个参与的人都熟悉)转移到数据库+ asp.net core Web应用程序解决方案(这将花费大量的时间和精力来构建。另外,没有网格组件匹配据我所知,“excel”电子表格的灵活性和功能。)
有什么想法吗?
您有许多从主文件(“主文件”)创建的电子表格(“部分文件”)。当在任何部分文件中进行更改时,您希望更改和适当的背景颜色反映在主文件中。
考虑这个答案:
onEdit
触发器在每个部分电子表格中触发逻辑
处理很简单,没有什么奇怪的,并且使用了事件对象。
其他注意事项:
function updateMaster(e) {
// Logger.log(JSON.stringify(e)) // DEBUG
// get Event Objects
var editedValue=e.value
var editedSheet = e.range.getSheet().getName()
var editedRow = e.range.rowStart
var editedCol = e.range.columnStart
var spreadsheetName = e.source.getName()
// get variables
var sheet2Watch = "Partial"
// Logger.log("DEBUG: edited value = "+editedValue+", edited sheet = "+editedSheet+", edited row = "+editedRow+", edited Column = "+editedCol+", spreadsheet Name = "+spreadsheetName)
if (editedSheet != sheet2Watch){
// no match, do nothing
// Logger.log("DEBUG: no match on sheet do nothing")
return
}
else if ( editedRow < 2){
// no match, do nothing
// Logger.log("DEBUG: no match on row, do nothing")
return
}
else if (editedCol !=2 && editedCol !=3){
// no match, do nothing
// Logger.log("DEBUG: no match on column, do nothing")
return
}
// Logger.log("DEBUG: valid edit")
// test for key in that row
var partial = e.source.getSheetByName(sheet2Watch)
var key = partial.getRange(editedRow,1).getValue()
// Logger.log("DEBUG: the key range = "+partial.getRange(editedRow,1).getA1Notation()+", and key = "+key+", key length = "+key.length)
if (key.length !=0 ){
// key exists
// Logger.log("DEBUG: There's a key in this row")
}
else{
// no key in this row, do nothing
// Logger.log("DEBUG: no key in this row, do nothing")
return
}
// get the colour to update
var colors = ["#FAD437","#7CF926"]
var updateColor = colors[editedCol-2]
// update color of the edited cell
// Logger.log("DEBUG: the edited cell = "+partial.getRange(editedRow,editedCol).getA1Notation())
partial.getRange(editedRow,editedCol).setBackground(updateColor)
// get the master data
var masterId = "<insert master ID>"
var masterSpreadsheet = SpreadsheetApp.openById(masterId)
var masterSheet = masterSpreadsheet.getSheetByName("Master")
// get master data
var masterData = masterSheet.getDataRange().getValues()
// remove the headers
masterData.shift()
// get column A (keys)
var masterKeys = masterData.map(function(e){return e[0]})
// Logger.log(masterKeys) // DEBUG
// find the index of the partial key on the master
var masterIndex = masterKeys.indexOf(key)
if (masterIndex == -1){
// if result = -1 then key not found
// send message to someone.
return
}
// Logger.log("DEBUG: key index on master = "+masterIndex)
// get the range to update
var masterUpdateRange = masterSheet.getRange((+masterIndex+2),editedCol)
// Logger.log("DEBUG: Master range to update = "+masterUpdateRange.getA1Notation())
// update the value and color in the Master
masterUpdateRange.setValue(editedValue).setBackground(updateColor)
}
之前 - 大师
之前 - 部分
之后 - 大师
之后 - 部分