Referência de célula com formatação de cores

16

É possível fazer referência a uma célula no Planilhas Google para que a célula onde ela é exibida também a exiba usando a mesma formatação de texto e cor de célula?

=A1

Referenciará apenas o valor da célula. Mas se essa célula em particular tiver fundo vermelho e texto em branco, eu gostaria que também fosse copiada.

Estou inclinado a soluções de fórmula existentes, em vez de scripts. Se aplicável, é claro.

Robert Koritnik
fonte
Este site é apenas para aplicativos da web. O Microsoft Excel não faz parte disso. Além disso, o Excel usa o VBA e o Google Spreadsheets usa o Google Apps Script para esse tipo de solução. Edite sua pergunta ou faça-a no SU.
: 9603 Jacob Jan Tuinstra
@JacobJanTuinstra: Eu estava ansioso por alguma fórmula já presente que eu pudesse usar. E como o Google Spreadsheets abrange muitas fórmulas presentes no Excel, eu também a adicionei como tag. Mas, caso contrário, eu sei que isso é sobre aplicativos da web. Eu já vi várias perguntas marcadas com o Excel de qualquer maneira, daí a minha tag. Mas obrigada. Não o adicionará no futuro.
9788 Robert Gallitnik #
1
Robert, existem muitas diferenças entre o Google Spreadsheets e o Microsoft Excel (2010). Veja a resposta que eu dei: webapps.stackexchange.com/a/44719/29140
Jacob Jan Tuinstra
1
@JacobJanTuinstra: Então, muitos muitos estão se referindo a esses 85%. Isso prova que abrange a maioria das fórmulas do Excel. :) E obrigado por postar o link. Ótima visão.
9788 Robert Patitnik # 03

Respostas:

8

Para as planilhas do Google, é possível escrever um script:

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);
}

Adicione um gatilho para a função de script, para que seja executada em todas as modificações da planilha.

Criei uma planilha de exemplo aqui . Sinta-se à vontade para copiá-lo em sua própria conta e comece a experimentar.

Vidar S. Ramdal
fonte
Não afirmei isso claramente na minha pergunta, mas estava mais focado nas fórmulas existentes e não nos scripts. Se não há combinação fórmula para fazer este trabalho, então o seu roteiro seria muito melhor se ele foi usado como uma fórmula chamada isto é fullCellRef(cellReference)assim pode-se usá-lo como =fullCellRef(A1)por exemplo
Robert Koritnik
Ah entendo. Mas não acho (me corrija se estiver errado) que exista alguma fórmula que especifique a formatação.
Vidar S. Ramdal
Corrigiria se definitivamente soubesse daqui minha pergunta. :) Mas caso contrário. Eu suspeito que não há nenhum. Portanto, se você reescrever seu script para ser usado como uma fórmula de célula, aceitarei sua resposta, pois seria a melhor solução possível para os recursos disponíveis.
Robert Koritnik
1
Hmm, atualmente não sei como uma função de fórmula de célula pode fazer referência à célula da qual é usada, o que é necessário para definir a formatação. Eu vou fazer uma pesquisa.
Vidar S. Ramdal
Não, desculpe, isso parece impossível. Uma função de fórmula não tem acesso para definir a formatação da célula. Então eu vou ter que deixar você com a opção de gatilho.
Vidar S. Ramdal
5

Usando as respostas de Vidar e Jacob como base, criei a seguinte solução que permitirá que você escreva = fullCellRef (A1), que copiará o valor e o formato de A1.

Um efeito colateral menor é que, se você arrastar e copiar uma célula com esta fórmula, as novas células inicialmente copiarão a formatação da célula original (como é normal), mas depois mudarão para a formatação mencionada após uma pequena pausa.

Folha de amostra aqui .

/**
 * 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;
}
Tom Horwood
fonte
Há um erro nas linhas 52 e 53 para o script de Tom. Alguém pode ajudar a executá-lo corretamente.
@SwapnilGosavi - Acabei de atualizar o código para incluir formatos adicionais e ele parece funcionar corretamente. Deixe-me saber se você ainda tem problemas
Tom Horwood
Isso é incrível. No entanto, ao ler o código-fonte, isso não funcionaria em todas as guias, correto?
Jade
@ Jade - Não - não funcionaria em guias. Poderia ser feito para fazê-lo, embora eu realmente não tenha investigado.
Tom Horwood #
3

É o mais próximo que você pode chegar, de ter uma sensação de fórmula.

Código

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);
}

Explicado

Na edição, uma caixa de mensagem é exibida e solicita um valor de entrada (menos também é permitido). Então a formatação (valor incluído), como Vidar maravilhosamente já apresentado, é aplicada.

Exemplo

Arquivo de Vidar copiado: Formatação de Células

Jacob Jan Tuinstra
fonte
Legal! Talvez você possa registrar seu gatilho como 'em modificação', em vez de 'em edição'. Assim, as alterações somente de formato serão propagadas também.
Vidar S. Ramdal