การอ้างอิงเซลล์ด้วยการจัดรูปแบบสี


16

เป็นไปได้หรือไม่ที่จะอ้างอิงเซลล์ใน Google ชีตเพื่อให้เซลล์ที่ได้รับการแสดงยังแสดงโดยใช้การจัดรูปแบบข้อความและสีของเซลล์เดียวกัน

=A1

จะอ้างอิงค่าของเซลล์เท่านั้น แต่ถ้าเซลล์นั้นมีพื้นหลังสีแดงและข้อความสีขาวฉันก็อยากจะคัดลอกเช่นกัน

ฉันเรียนวิธีแก้ปัญหาสูตรที่มีอยู่มากกว่าสคริปต์ ถ้าใช้แน่นอน


ไซต์นี้มีไว้สำหรับเว็บแอปพลิเคชันเท่านั้น Microsoft Excel ไม่ได้เป็นส่วนหนึ่งของสิ่งนั้น นอกจากนี้ Excel ยังใช้ VBA และ Google Spreadsheets ใช้ Google Apps Script สำหรับโซลูชันประเภทนี้ โปรดแก้ไขคำถามของคุณหรือถามคำถามอื่นใน SU
จาค็อบ ม.ค. Tuinstra

@JacobJanTuinstra: ฉันตั้งตารอที่จะนำเสนอสูตรที่ฉันสามารถใช้ได้ และเนื่องจาก Google Spreadsheets ครอบคลุมหลายสูตรอยู่ใน Excel ฉันจึงเพิ่มเป็นแท็กด้วย แต่อย่างอื่นฉันรู้ว่านี่เป็นเรื่องเกี่ยวกับเว็บแอป ฉันเห็นคำถามหลายข้อติดแท็กด้วย Excel แล้วดังนั้นแท็กของฉัน แต่ขอบคุณ. จะไม่เพิ่มในอนาคต
Robert Koritnik

1
Robert มีความแตกต่างมากมายระหว่าง Google Spreadsheets และ Microsoft Excel (2010) ดูคำตอบที่ฉันให้: webapps.stackexchange.com/a/44719/29140
Jacob Jan Tuinstra

1
@JacobJanTuinstra: หลาย ๆ คนของฉันอ้างอิงถึง 85% นี่เป็นการพิสูจน์ว่ามันครอบคลุมสูตรส่วนใหญ่ของ Excel :) และขอบคุณสำหรับการโพสต์ลิงค์ ความเข้าใจที่ยอดเยี่ยม
Robert Koritnik

คำตอบ:


8

สำหรับ Google Spreadsheets สามารถทำได้โดยการเขียนสคริปต์:

function copyValuesAndFormatting() {
    var sheet = SpreadsheetApp.getActiveSpreadsheet();

    var fromRange = sheet.getRange("A2:A");
    var toRange = sheet.getRange("B2:B");
    var values = fromRange.getValues();
    var fontColors = fromRange.getFontColors();
    var backgrounds = fromRange.getBackgrounds();
    var fonts = fromRange.getFontFamilies();
    var fontWeights = fromRange.getFontWeights();
    var fontStyles = fromRange.getFontStyles();

    toRange.setBackgrounds(backgrounds);
    toRange.setFontColors(fontColors);
    toRange.setValues(values);
    toRange.setFontFamilies(fonts);
    toRange.setFontWeights(fontWeights);
    toRange.setFontStyles(fontStyles);
}

เพิ่มทริกเกอร์สำหรับฟังก์ชั่นสคริปต์เพื่อให้มันทำงานในทุกการแก้ไขสเปรดชีต

ฉันสร้างสเปรดชีตตัวอย่างที่นี่แล้ว คุณสามารถคัดลอกไปยังบัญชีของคุณเองและเริ่มทดลองกับมันได้


ฉันไม่ได้ระบุไว้อย่างชัดเจนในคำถามของฉัน แต่ฉันดูสูตรที่มีอยู่มากกว่าไม่ใช่สคริปต์ หากไม่มีการรวมสูตรเพื่อทำให้งานนี้เป็นจริงสคริปต์ของคุณจะดีขึ้นมากหากใช้เป็นสูตรที่เรียกว่าfullCellRef(cellReference)ดังนั้นจึงสามารถใช้เป็น=fullCellRef(A1)ตัวอย่างได้
Robert Koritnik

อ่าฉันเข้าใจแล้ว แต่ฉันไม่คิดว่า (แก้ไขฉันถ้าฉันผิด) มีสูตรใด ๆที่ระบุการจัดรูปแบบ
Vidar S. Ramdal

ฉันจะแก้ไขให้คุณถ้าฉันรู้แน่นอนว่าด้วยคำถามของฉัน :) แต่อย่างอื่น ฉันสงสัยว่าจะไม่มีใครอยู่ดี ดังนั้นหากคุณเขียนสคริปต์ของคุณเพื่อใช้เป็นสูตรเซลล์ฉันจะยอมรับคำตอบของคุณเพราะมันจะเป็นทางออกที่ดีที่สุดสำหรับคุณสมบัติในมือ
Robert Koritnik

1
อืมตอนนี้ฉันไม่ทราบว่าฟังก์ชั่นสูตรเซลล์สามารถอ้างอิงเซลล์ที่ใช้มาได้อย่างไรซึ่งจำเป็นสำหรับการจัดรูปแบบ ฉันจะทำการวิจัย
Vidar S. Ramdal

ไม่ขอโทษดูเหมือนว่าจะเป็นไปไม่ได้ ฟังก์ชั่นสูตรไม่สามารถเข้าถึงการตั้งค่าการจัดรูปแบบเซลล์ ดังนั้นฉันจะต้องทิ้งคุณไว้กับตัวเลือกทริกเกอร์
Vidar S. Ramdal

5

การใช้คำตอบของ Vidar และ Jacob เป็นพื้นฐานฉันได้สร้างโซลูชันต่อไปนี้ซึ่งจะช่วยให้คุณเขียน = fullCellRef (A1) ซึ่งจะคัดลอกค่าและรูปแบบจาก A1

ผลข้างเคียงเล็กน้อยคือถ้าคุณลากคัดลอกเซลล์ด้วยสูตรนี้เซลล์ใหม่จะเริ่มคัดลอกการจัดรูปแบบของเซลล์ดั้งเดิม (ตามปกติ) แต่จะสลับไปใช้การจัดรูปแบบอ้างอิงหลังจากหยุดชั่วคราวเล็กน้อย

แผ่นตัวอย่างที่นี่

/**
 * Dummy function to be the equivalent of using simple reference,
 * but is used to identify which cells to copy format.
 * The immediate effect of =fullCellRef(A1) is the same as =A1
 * 
 * @param  {string} value The value of the referred cell
 * @return {string}       The given value
 */
function fullCellRef(value){
  return value;
}

/**
 * For each cell with the formula eg B2=fullCellRef(A1), the format of
 * the referred cell (eg A1) is copied to the calling cell (eg B2)
 */
function copyFormatting() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getDataRange();
  var offsetRow = range.getRow() - 1;
  var offsetCol = range.getColumn() - 1;

  var formulas = range.getFormulas();

  var formats = {
    fontColors: range.getFontColors(),
    backgrounds: range.getBackgrounds(),
    fonts: range.getFontFamilies(),
    fontWeights: range.getFontWeights(),
    fontStyles: range.getFontStyles(),
    verticalAlignments: range.getVerticalAlignments(),
    horizontalAlignments: range.getHorizontalAlignments(),
    numberFormats: range.getNumberFormats()
  };
  var formulaIsUsed = false;
  for (var row = 0; row < formulas.length; row ++ ) {
    for (var column = 0; column < formulas[row].length; column ++ ) {
      var refersTo = findReferenceCells(formulas[row][column]);
      if (refersTo){
        formulaIsUsed = true;
        var refRow = refersTo.row - offsetRow;
        var refCol = refersTo.column - offsetCol;
        for (var key in formats) {
          formats[key][row][column] = formats[key][refRow][refCol];
        }
      }
    }
  }

  if (formulaIsUsed) {
    range.setBackgrounds(formats.backgrounds);
    range.setFontColors(formats.fontColors);
    range.setFontFamilies(formats.fonts);
    range.setFontWeights(formats.fontWeights);
    range.setFontStyles(formats.fontStyles); 
    range.setVerticalAlignments(formats.verticalAlignments);
    range.setHorizontalAlignments(formats.horizontalAlignments);
    range.setNumberFormats(formats.numberFormats);
  }

}

/**
 * Returns the 2D array indices to identify the referred cell.
 * @param  {string} formula The cell formula
 * @return {Array.integer}         The row and column array indices
 */
function findReferenceCells(formula) {
  if (formula === "") {
    return false;
  }
  var refPattern = /^=fullcellref\(([a-z]{1,2})(\d+)\)$/i;
  var matches = refPattern.exec(formula.replace(" ", ""));
  matches.shift();
  if (!matches) {
    return false;
  }
  // convert cell reference to array indices
  var column = colToInteger(matches[0]) - 1;
  var row = matches[1] - 1;

  return {row: row, column: column};
}

/**
 * Converts a column name to a column number
 * @param  {string} columnName eg "A", "BB"
 * @return {integer}            Between 1 and 256
 */
function colToInteger(columnName){
  var nameParts = columnName.toLowerCase().split();
  //97 is char code of "a", but we need 1 based indices
  var colNum = nameParts.pop().charCodeAt(0) - 96;
  if (nameParts.length === 1){
    colNum += 26 * (nameParts.pop().charCodeAt(0) - 96);
  }
  return colNum;
}

มีข้อผิดพลาดในบรรทัดที่ 52 และ 53 สำหรับสคริปต์ของทอม ใครบางคนสามารถช่วยในการดำเนินการอย่างถูกต้อง

@SwapnilGosavi - ฉันเพิ่งอัปเดตรหัสเพื่อรวมรูปแบบเพิ่มเติมและดูเหมือนว่าจะทำงานอย่างถูกต้อง แจ้งให้เราทราบหากคุณยังมีปัญหาอยู่
Tom Horwood

นี่มันสุดยอดมาก อย่างไรก็ตามในขณะที่ฉันอ่านซอร์สโค้ดสิ่งนี้จะไม่ทำงานกับแท็บถูกต้องหรือไม่
Jade

@Jade - ไม่ - มันใช้ไม่ได้กับหลายแท็บ อาจเป็นไปได้ที่จะทำเช่นนั้นแม้ว่าฉันจะไม่ได้ดูมันจริงๆ
Tom Horwood

3

นี่คือสิ่งที่ใกล้เคียงที่สุดที่คุณจะได้รับเมื่อรู้สึกถึงสูตร

รหัส

function onEdit(e) {
  var sh = e.source.getActiveSheet();
  var aCell = sh.getActiveCell(), value = aCell.getValue();

  // get formatting
  var fontColor = aCell.getFontColor();
  var background = aCell.getBackground();
  var font = aCell .getFontFamily();
  var fontWeight = aCell.getFontWeight();
  var fontStyle = aCell.getFontStyle();
  var target = Browser.inputBox('Give column number, relative to active cell', 
    Browser.Buttons.OK);
  var tCell = aCell.offset(0,parseInt(target));

  // set formatting
  tCell.setBackground(background).setFontColor(fontColor).setFontFamily(font)
    .setFontWeight(fontWeight).setFontStyle(fontStyle).setValue(value);
}

อธิบาย

เมื่อแก้ไขจะมีกล่องข้อความปรากฏขึ้นและขอค่าอินพุต (อนุญาตให้ลบด้วย) จากนั้นจะใช้การจัดรูปแบบ (รวมค่า) ตามที่ Vidar นำเสนออย่างน่าอัศจรรย์แล้ว

ตัวอย่าง

คัดลอกไฟล์ของ Vidar แล้ว: การจัดรูปแบบเซลล์


เย็น! บางทีคุณสามารถลงทะเบียนทริกเกอร์ของคุณเป็น 'ในการปรับเปลี่ยน' แทน 'ในการแก้ไข' ดังนั้นการเปลี่ยนแปลงรูปแบบเท่านั้นจะเผยแพร่เช่นกัน
Vidar S. Ramdal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.