Odwołanie do komórki z formatowaniem kolorów

16

Czy można odwoływać się do komórki w Arkuszach Google, aby komórka, w której jest wyświetlana, wyświetlała ją również przy użyciu tego samego formatu tekstu i koloru komórki?

=A1

Odwołuje się tylko do wartości komórki. Ale jeśli ta konkretna komórka ma czerwone tło i biały tekst, chciałbym, aby również ją skopiować.

Skłaniam się ku istniejącym rozwiązaniom formuł, a nie skryptom. Jeśli dotyczy, oczywiście.

Robert Koritnik
źródło
Ta strona jest przeznaczona wyłącznie do aplikacji internetowych. Microsoft Excel nie jest tego częścią. Ponadto Excel używa VBA, a Arkusze kalkulacyjne Google używają Google Apps Script do tego rodzaju rozwiązań. Edytuj swoje pytanie lub zadaj je na SU.
Jacob Jan Tuinstra
@JacobJanTuinstra: Nie mogłem się doczekać jakiejś już obecnej formuły, której mógłbym użyć. A ponieważ arkusze kalkulacyjne Google obejmują wiele formuł obecnych w programie Excel, dodałem go również jako tag. Ale poza tym wiem, że chodzi o aplikacje internetowe. W każdym razie widziałem kilka pytań oznaczonych Excelem, stąd mój tag. Ale dzięki. Nie dodam tego w przyszłości.
Robert Koritnik
1
Robert, istnieje wiele różnych różnic między Arkuszami kalkulacyjnymi Google a Microsoft Excel (2010). Zobacz odpowiedź, którą dałem: webapps.stackexchange.com/a/44719/29140
Jacob Jan Tuinstra
1
@JacobJanTuinstra: Tak wielu moich odnosi się do tych 85%. Dowodzi to, że obejmuje większość formuł programu Excel. :) I dzięki za opublikowanie linku. Świetny wgląd.
Robert Koritnik

Odpowiedzi:

8

W przypadku Arkuszy kalkulacyjnych Google jest to możliwe, pisząc skrypt:

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

Dodaj wyzwalacz dla funkcji skryptu, aby działał przy każdej modyfikacji arkusza kalkulacyjnego.

I stworzyliśmy przykładowy arkusz tutaj . Skopiuj go na własne konto i zacznij eksperymentować z nim.

Vidar S. Ramdal
źródło
Nie wyraziłem tego jasno w moim pytaniu, ale bardziej szukałem istniejących formuł, a nie skryptów. Jeśli nie ma kombinacji formuł, która by działała, twój skrypt byłby znacznie lepszy, gdyby był użyty jako formuła o nazwie tj. fullCellRef(cellReference)Można by go użyć =fullCellRef(A1)na przykład
Robert Koritnik
O, rozumiem. Ale nie sądzę (popraw mnie, jeśli się mylę) istnieje jakaś formuła, która określa formatowanie.
Vidar S. Ramdal,
Poprawiłbym cię, gdybym zdecydowanie wiedział, stąd moje pytanie. :) Ale inaczej. Podejrzewam, że i tak nie ma. Więc jeśli przepiszesz skrypt, aby był używany jako formuła komórkowa, zaakceptuję twoją odpowiedź, ponieważ byłoby to najlepsze możliwe rozwiązanie dla dostępnych funkcji.
Robert Koritnik
1
Hmm, obecnie nie wiem, jak funkcja formuły komórkowej może odwoływać się do komórki, z której jest używana, co jest konieczne do ustawienia formatowania. Zrobię trochę badań.
Vidar S. Ramdal,
Nie, przepraszam, wydaje się to niemożliwe. Funkcja formuły nie ma dostępu do ustawiania formatowania komórki. Więc muszę zostawić cię z opcją wyzwalania.
Vidar S. Ramdal
5

Na podstawie odpowiedzi Vidara i Jacoba stworzyłem następujące rozwiązanie, które pozwoli Ci napisać = fullCellRef (A1), który skopiuje wartość i format z A1.

Niewielki efekt uboczny polega na tym, że jeśli przeciągniesz komórkę za pomocą tej formuły, nowe komórki początkowo skopiują formatowanie oryginalnej komórki (co jest normalne), ale po krótkiej przerwie przełączy się na formatowanie, do którego się odwołuje.

Przykładowy arkusz tutaj .

/**
 * 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
źródło
W skrypcie Toma wystąpił błąd w wierszach 52 i 53. Czy ktoś może pomóc w prawidłowym wykonaniu tego.
@ SwapnilGosavi - Właśnie zaktualizowałem kod, aby zawierał dodatkowe formaty i wydaje się, że działa poprawnie. Daj mi znać, jeśli nadal masz problemy
Tom Horwood
To jest niesamowite. Jednak gdy czytam kod źródłowy, nie działałoby to między kartami, prawda?
Jade
@Jade - Nie - nie działałoby na różnych kartach. Można tego dokonać, chociaż tak naprawdę nie przyjrzałem się temu.
Tom Horwood,
3

To jest najbliższe, jakie możesz uzyskać, mając poczucie formuły.

Kod

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

Wyjaśniono

Podczas edycji pojawi się okno komunikatu z prośbą o podanie wartości wejściowej (dozwolony jest również minus). Następnie stosuje się formatowanie (w tym wartość), jak cudownie już zaprezentował Vidar.

Przykład

Skopiowano plik Vidar: Formatowanie komórki

Jacob Jan Tuinstra
źródło
Chłodny! Być może mógłbyś zarejestrować swój wyzwalacz jako „przy modyfikacji”, zamiast „przy edycji”. W związku z tym propagowane będą również zmiany tylko w formacie.
Vidar S. Ramdal