Google E-Tablolar ile 4. Apps Komut Dosyasının Temelleri: Veri Biçimlendirme

1. Giriş

Google E-Tablolar ile Codelab oynatma listesinin dördüncü bölümüne hoş geldiniz.

Bu codelab'i tamamlayarak Apps Komut Dosyası'ndaki e-tablo verilerinizi nasıl biçimlendireceğinizi öğrenebilir ve herkese açık bir API'den getirilen biçimlendirilmiş verilerle dolu e-tablolar oluşturmak için işlevler yazabilirsiniz.

Neler öğreneceksiniz?

  • Apps Komut Dosyası'nda çeşitli Google E-Tablolar biçimlendirme işlemlerini uygulama.
  • Apps Komut Dosyası'nı kullanarak JSON nesneleri ve özelliklerinin listesini organize edilmiş bir veri sayfasına dönüştürme.

Başlamadan önce

Bu, Google E-Tablolar ile Apps Komut Dosyası'nın Temelleri oynatma listesinde dördüncü kod laboratuvarıdır. Bu codelab'e başlamadan önce önceki codelab'leri tamamladığınızdan emin olun:

  1. Makrolar ve Özel İşlevler
  2. E-tablolar, E-Tablolar ve Aralıklar
  3. Verilerle çalışma

Gerekenler

  • Bu oynatma listesinin önceki codelab'lerinde incelenen temel Apps Komut Dosyası konuları hakkında bilgi edinin.
  • Apps Komut Dosyası düzenleyicisine dair temel bilgi sahibi olma
  • Google E-Tablolar'la ilgili temel bilgi sahibi olma
  • E-Tablolar A1 Gösterimi'ni okuma özelliği
  • JavaScript ve String sınıfı hakkında temel bilgi sahibi olma

2. Kur

Devam etmeden önce bazı verilerin bulunduğu bir e-tabloya ihtiyacınız var. Daha önce olduğu gibi, bu alıştırmalarda kullanabileceğiniz bir veri sayfası hazırladık. Aşağıdaki adımları uygulayın:

  1. Veri sayfasını kopyalamak için bu bağlantıyı tıklayın ve ardından Kopya oluştur'u tıklayın. Yeni e-tablo, Google Drive klasörünüze yerleştirilir ve "Veri Biçimlendirmesi Kopyası" olarak adlandırılır.
  2. E-tablo başlığını tıklayın ve bunu "Veri Biçimlendirmesi Kopyası" yerine "Veri Biçimlendirme" olarak değiştirin. E-tablonuz, ilk üç Star Wars filmiyle ilgili bazı temel bilgilerle birlikte şöyle görünmelidir:

c4f49788ed82502b.png

  1. Komut dosyası düzenleyiciyi açmak için Uzantılar> Apps Komut Dosyası'nı seçin.
  2. Apps Komut Dosyası proje başlığını tıklayın ve "Başlıksız proje" yerine "Veri Biçimlendirme" olarak değiştirin. Başlık değişikliğini kaydetmek için Yeniden adlandır'ı tıklayın.

Bu e-tablo ve projeyle codelab'i başlatmaya hazırsınız. Apps Komut Dosyası'ndaki temel biçimlendirme hakkında bilgi edinmeye başlamak için bir sonraki bölüme geçin.

3. Özel menü oluşturma

Apps Komut Dosyası'ndaki birkaç temel biçimlendirme yöntemini E-Tablolarınıza uygulayabilirsiniz. Aşağıdaki alıştırmalarda verileri biçimlendirmenin birkaç yolu gösterilmiştir. Biçimlendirme işlemlerinizi kontrol etmenize yardımcı olmak için, ihtiyacınız olan öğeleri içeren özel bir menü oluşturalım. Özel menü oluşturma işlemi Verilerle çalışma codelab'inde açıklanmıştır. Ancak bunu tekrar özetleyeceğiz.

Uygulama

Özel bir menü oluşturalım.

  1. Apps Komut Dosyası düzenleyicisinde, komut dosyası projenizdeki kodu aşağıdaki gibi değiştirin:
/**
 * A special function that runs when the spreadsheet is opened
 * or reloaded, used to add a custom menu to the spreadsheet.
 */
function onOpen() {
  // Get the spreadsheet's user-interface object.
  var ui = SpreadsheetApp.getUi();

  // Create and add a named menu and its items to the menu bar.
  ui.createMenu('Quick formats')
   .addItem('Format row header', 'formatRowHeader')
   .addItem('Format column header', 'formatColumnHeader')
   .addItem('Format dataset', 'formatDataset') 
  .addToUi();
}
  1. Komut dosyası projenizi kaydedin.
  2. Komut dosyası düzenleyicisinde, işlevler listesinden onOpen'yi seçin ve Çalıştır'ı tıklayın. Bunu yaptığınızda onOpen(), e-tablo menüsünü yeniden oluşturur. Böylece e-tabloyu yeniden yüklemenize gerek kalmaz.

Kod incelemesi

Nasıl çalıştığını anlamak için bu kodu inceleyelim. onOpen() dosyasında ilk satır, bu komut dosyasının bağlı olduğu etkin e-tablonun kullanıcı arayüzünü temsil eden Ui nesnesi edinmek için getUi() yöntemini kullanır.

Sonraki satırlarda bir menü oluşturulur (Quick formats), menüye menü öğeleri (Format row header, Format column header ve Format dataset) ekleyin, ardından menüyü e-tablo arayüzüne ekleyin. Bu işlem sırasıyla createMenu(caption), addItem(caption, functionName) ve addToUi() yöntemleriyle yapılır.

addItem(caption, functionName) yöntemi, menü öğesi seçildiğinde menü öğesi etiketi ile çalışan bir Apps Komut Dosyası işlevi arasında bir bağlantı oluşturur. Örneğin, Format row header menü öğesinin seçilmesi E-Tablolar'ın formatRowHeader() işlevini çalıştırmasına (henüz mevcut değildir) neden olur.

Sonuçlar

E-tablonuzda, yeni menüyü görüntülemek için Quick formats menüsünü tıklayın:

1d639a41f3104864.png

Bu öğeleri tıklamak, karşılık gelen işlevlerini uygulamadığınız için bir hataya neden olur. Bu nedenle işlemi şimdi yapalım.

4. Başlık satırını biçimlendirme

E-tablolardaki veri kümeleri genellikle her sütundaki verileri tanımlamak için başlık satırlarına sahiptir. Başlık satırlarını, e-tablodaki diğer verilerden görsel olarak ayıracak şekilde biçimlendirmeniz iyi bir fikirdir.

İlk codelab'de, başlığınız için bir makro oluşturdunuz ve kodunu ayarladınız. Burada, Apps Komut Dosyası'nı kullanarak sıfırdan bir başlık satırı biçimlendirebilirsiniz. Oluşturacağınız başlık satırı başlık metnini kalın hale getirir, arka planı koyu mavi-yeşil, metni beyaz ve kalın kenarlıklar ekler.

Uygulama

Biçimlendirme işlemini uygulamak için daha önce kullandığınız E-tablo hizmeti yöntemlerini aynı şekilde kullanacaksınız. Ancak artık hizmetin bazı biçimlendirme yöntemlerini de kullanacaksınız. Aşağıdaki adımları uygulayın:

  1. Apps Komut Dosyası düzenleyicisinde, komut dosyası projenizin sonuna aşağıdaki işlevi ekleyin:
/**
 * Formats top row of sheet using our header row style.
 */
function formatRowHeader() {
  // Get the current active sheet and the top row's range.
  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
 
  // Apply each format to the top row: bold white text,
  // blue-green background, and a solid black border
  // around the cells.
  headerRange
    .setFontWeight('bold')
    .setFontColor('#ffffff')
    .setBackground('#007272')
    .setBorder(
      true, true, true, true, null, null,
      null,
      SpreadsheetApp.BorderStyle.SOLID_MEDIUM);

}
  1. Komut dosyası projenizi kaydedin.

Kod incelemesi

Birçok biçimlendirme görevi gibi Apps Komut Dosyası'nın kodu da basit bir şekilde uygulanır. İlk iki satır, geçerli etkin sayfaya (sheet) ve sayfanın en üst satırına (headerRange)) referans almak için daha önce gördüğünüz yöntemleri kullanır. Sheet.getRange(row, column, numRows, numColumns) yöntemi, yalnızca veri içeren sütunları içeren en üst satırı belirtir. Sheet.getLastColumn() yöntemi, sayfadaki verileri içeren son sütunun sütun dizinini döndürür. Örneğimizde, E (url) sütunu.

Kodun geri kalanı, biçimlendirme seçeneklerini headerRange içindeki tüm hücrelere uygulamak için çeşitli Range yöntemlerini çağırır. Kodun kolay okunabilir olmasını sağlamak için, her biçimlendirme yöntemini birbiri ardına çağırmak üzere yüzme zincirini kullanırız kullanırız:

Son yöntem birkaç parametre içerir. Bu nedenle, her birinin işlevini inceleyelim. Buradaki ilk dört parametre (tümü true olarak ayarlanmıştır), Apps Komut Dosyası'na sınırın üst, alt ve aralığın sol ve sağ kısmına eklenmesi gerektiğini belirtir. Beşinci ve altıncı parametreler (null ve null), seçilen aralıktaki sınır çizgilerini değiştirmemek için Apps Komut Dosyasını yönlendirir. Yedinci parametre (null), kenarlığın renginin varsayılan olarak siyah olması gerektiğini belirtir. Son olarak, SpreadsheetApp.BorderStyle tarafından sağlanan seçenekler arasından kullanılacak sınır stilinin son parametresi belirtilir.

Sonuçlar

Biçimlendirme işlevinizi çalışırken şunları görebilirsiniz:

  1. Henüz yapmadıysanız komut dosyası projenizi Apps Komut Dosyası düzenleyicisine kaydedin.
  2. Hızlı biçimler ve > Satır başlığını biçimlendir menü öğesini tıklayın.

Sonuçlar aşağıdaki gibi olacaktır:

a1a63770c2c3becc.gif

Artık bir biçimlendirme görevini otomatik hale getirdiniz. Sonraki bölümde, sütun başlıkları için farklı bir biçim stili oluşturmak için aynı teknik uygulanır.

5. Sütun başlığını biçimlendirme

Kişiselleştirilmiş bir satır başlığı da oluşturursanız sütun başlığı da oluşturabilirsiniz. Sütun başlıkları, belirli veri kümelerinin okunabilirliğini artırır. Örneğin, bu e-tablodaki titles sütunu aşağıdaki biçim seçenekleriyle geliştirilebilir:

  • Metni kalınlaştırma
  • İtalik metin
  • Hücre kenarlıkları ekleme
  • url sütun içeriğini kullanarak köprü ekleme. Bu köprüleri ekledikten sonra, sayfayı temizlemenize yardımcı olması için url sütununu kaldırabilirsiniz.

Ardından, bu değişiklikleri sayfadaki ilk sütuna uygulamak için bir formatColumnHeader() işlevi uygularsınız. Kodun daha kolay okunabilmesi için iki yardımcı işlev de uygularsınız.

Uygulama

Daha önce olduğu gibi, sütun başlığı biçimlendirmesini otomatikleştirmek için bir işlev eklemeniz gerekir. Aşağıdaki adımları uygulayın:

  1. Apps Komut Dosyası düzenleyicisinde, komut dosyası projenizin sonuna aşağıdaki formatColumnHeader() işlevini ekleyin:
/**
 * Formats the column header of the active sheet.
 */ 
function formatColumnHeader() {  
  var sheet = SpreadsheetApp.getActiveSheet();
  
  // Get total number of rows in data range, not including
  // the header row.
  var numRows = sheet.getDataRange().getLastRow() - 1;
  
  // Get the range of the column header.
  var columnHeaderRange = sheet.getRange(2, 1, numRows, 1);
  
  // Apply text formatting and add borders.
  columnHeaderRange
    .setFontWeight('bold')
    .setFontStyle('italic')
    .setBorder(
      true, true, true, true, null, null,
      null,
      SpreadsheetApp.BorderStyle.SOLID_MEDIUM);
 
  // Call helper method to hyperlink the first column contents
  // to the url column contents.
  hyperlinkColumnHeaders_(columnHeaderRange, numRows); 
}
  1. Aşağıdaki yardımcı işlevleri, komut dosyası projenizin sonuna formatColumnHeader() işlevinden sonra ekleyin:
/**
 * Helper function that hyperlinks the column header with the
 * 'url' column contents. The function then removes the column.
 *
 * @param {object} headerRange The range of the column header
 *   to update.
 * @param {number} numRows The size of the column header.
 */
function hyperlinkColumnHeaders_(headerRange, numRows) {
  // Get header and url column indices.
  var headerColIndex = 1; 
  var urlColIndex = columnIndexOf_('url');  
  
  // Exit if the url column is missing.
  if(urlColIndex == -1)
    return; 
  
  // Get header and url cell values.
  var urlRange =
    headerRange.offset(0, urlColIndex - headerColIndex);
  var headerValues = headerRange.getValues();
  var urlValues = urlRange.getValues();
  
  // Updates header values to the hyperlinked header values.
  for(var row = 0; row < numRows; row++){
    headerValues[row][0] = '=HYPERLINK("' + urlValues[row]
      + '","' + headerValues[row] + '")';
  }
  headerRange.setValues(headerValues);
  
  // Delete the url column to clean up the sheet.
  SpreadsheetApp.getActiveSheet().deleteColumn(urlColIndex);
}

/**
 * Helper function that goes through the headers of all columns
 * and returns the index of the column with the specified name
 * in row 1. If a column with that name does not exist,
 * this function returns -1. If multiple columns have the same
 * name in row 1, the index of the first one discovered is
 * returned.
 * 
 * @param {string} colName The name to find in the column
 *   headers. 
 * @return The index of that column in the active sheet,
 *   or -1 if the name isn't found.
 */ 
function columnIndexOf_(colName) {
  // Get the current column names.
  var sheet = SpreadsheetApp.getActiveSheet();
  var columnHeaders =
    sheet.getRange(1, 1, 1, sheet.getLastColumn());
  var columnNames = columnHeaders.getValues();
  
  // Loops through every column and returns the column index
  // if the row 1 value of that column matches colName.
  for(var col = 1; col <= columnNames[0].length; col++)
  {
    if(columnNames[0][col-1] === colName)
      return col; 
  }

  // Returns -1 if a column named colName does not exist. 
  return -1; 
}
  1. Komut dosyası projenizi kaydedin.

Kod incelemesi

Şimdi bu üç işlevin her birindeki kodu inceleyelim:

formatColumnHeader()

Muhtemelen beklediğiniz gibi, bu işlevin ilk birkaç satırında ilgilendiğimiz sayfaya ve aralığa atıfta bulunan değişkenler ayarlanmıştır:

  • Etkin sayfa sheet içinde depolanıyor.
  • Sütun başlığındaki satır sayısı numRows içinde hesaplanır ve kaydedilir. Buradaki kod bunlardan birini çıkarır, böylece satır sayısı sütun başlığını içermez: title.
  • Sütun başlığını kaplayan aralık, columnHeaderRange cinsinden depolanır.

Daha sonra kod, formatRowHeader() öğesinde olduğu gibi kenarlıkları ve kalınlaştırmayı sütun başlığı aralığına uygular. Burada, Range.setFontStyle(fontStyle) metni italik hale getirmek için de kullanılır.

Başlık sütununa köprü ekleme işlemi daha karmaşıktır. Bu nedenle formatColumnHeader(), görevi tamamlamak için hyperlinkColumnHeaders_(headerRange, numRows) çağrısı yapar. Bu, kodun düzenli ve okunabilir olmasını sağlar.

hyperlinkColumnHeaders_(headerRange, numRows)

Bu yardımcı işlev, ilk olarak başlığın (dizin 1 olduğu varsayılır) sütun dizinlerini ve url sütununu tanımlar. URL sütun dizinini almak için columnIndexOf_('url') çağırır. Bir url sütunu bulunamazsa, yöntem herhangi bir veri değiştirmeden çıkar.

İşlev, başlık sütunu satırlarına karşılık gelen URL'leri kapsayan yeni bir aralık (urlRange) alır. Bu işlem, Range.offset(rowOffset, columnOffset) yöntemiyle yapılır. Bu, iki aralığın aynı boyutta olacağını garanti eder. Daha sonra, hem headerColumn hem de url sütunundaki değerler (headerValues ve urlValues) alınır.

İşlev, daha sonra her bir sütun başlığı hücresi değerinin üzerine gelip bunu başlık ve url sütun içeriğiyle oluşturulan bir =HYPERLINK() E-Tablolar formülü ile değiştirir. Değiştirilen başlık değerleri, daha sonra Range.setValues(values) kullanılarak sayfaya eklenir.

Son olarak, sayfayı temiz tutmaya ve gereksiz bilgileri ortadan kaldırmak için url sütununun kaldırılması için Sheet.deleteColumn(columnPosition) çağrılır.

columnIndexOf_(colName)

Bu yardımcı işlev, sayfanın ilk satırında belirli bir adı arayan basit bir yardımcı program işlevidir. İlk üç satır, e-tablonun 1. satırındaki sütun başlığı adlarının listesini almak için önceden gördüğünüz yöntemleri kullanır. Bu adlar, columnName değişkeninde depolanır.

İşlev, daha sonra her adı sırayla inceler. Aranan adla eşleşen bir giriş bulursa sütunun dizinini döndürür. Adı bulmadan ad listesinin sonuna ulaşırsa adın bulunamadığını belirtmek için -1 değerini döndürür.

Sonuçlar

Biçimlendirme işlevinizi çalışırken şunları görebilirsiniz:

  1. Henüz yapmadıysanız komut dosyası projenizi Apps Komut Dosyası düzenleyicisine kaydedin.
  2. Hızlı biçimler > Biçim sütun başlığı menü öğesini tıklayın.

Sonuçlar aşağıdaki gibi olacaktır:

7497cf1b982aeff6.gif

Şimdi başka bir biçimlendirme görevi otomatikleştirdiniz. Sütun ve satır başlıkları biçimlendirildiğinde sonraki bölümde verilerin nasıl biçimlendirileceği gösterilir.

6. Veri kümenizi biçimlendirme

Üstbilgileriniz olduğuna göre şimdi sayfanızdaki verilerin geri kalanını biçimlendiren bir işlev gerçekleştirebiliriz. Aşağıdaki biçimlendirme seçeneklerini kullanırız:

  • Alternatif satır arka plan renkleri (bantlama olarak bilinir)
  • Tarih biçimlerini değiştirme
  • Kenarlık uygulama
  • Tüm sütunları ve satırları otomatik olarak boyutlandırma

Şimdi formatDataset() işlevi ve bu biçimleri sayfa verilerinize uygulamak için fazladan bir yöntem oluşturacaksınız.

Uygulama

Daha önce olduğu gibi, veri biçimlendirmesini otomatikleştirmek için bir işlev ekleyin. Aşağıdaki adımları uygulayın:

  1. Apps Komut Dosyası düzenleyicisinde, komut dosyası projenizin sonuna aşağıdaki formatDataset() işlevini ekleyin:
/**
 * Formats the sheet data, excluding the header row and column.
 * Applies the border and banding, formats the 'release_date'
 * column, and autosizes the columns and rows.
 */
function formatDataset() {
  // Get the active sheet and data range.
  var sheet = SpreadsheetApp.getActiveSheet(); 
  var fullDataRange = sheet.getDataRange();

  // Apply row banding to the data, excluding the header
  // row and column. Only apply the banding if the range
  // doesn't already have banding set.
  var noHeadersRange = fullDataRange.offset(
    1, 1,
    fullDataRange.getNumRows() - 1,
    fullDataRange.getNumColumns() - 1);

  if (! noHeadersRange.getBandings()[0]) {
    // The range doesn't already have banding, so it's
    // safe to apply it.
    noHeadersRange.applyRowBanding(
      SpreadsheetApp.BandingTheme.LIGHT_GREY,
      false, false);
  }

  // Call a helper function to apply date formatting
  // to the column labeled 'release_date'.
  formatDates_( columnIndexOf_('release_date') );
  
  // Set a border around all the data, and resize the
  // columns and rows to fit.
  fullDataRange.setBorder(
    true, true, true, true, null, null,
    null,
    SpreadsheetApp.BorderStyle.SOLID_MEDIUM);

  sheet.autoResizeColumns(1, fullDataRange.getNumColumns());
  sheet.autoResizeRows(1, fullDataRange.getNumRows());
}
  1. Komut dosyası projenizin sonuna, formatDataset() işlevinin sonuna aşağıdaki yardımcı işlevi ekleyin:
/** 
 * Helper method that applies a
 * "Month Day, Year (Day of Week)" date format to the
 * indicated column in the active sheet. 
 *
 * @param {number} colIndex The index of the column
 *   to format.
 */ 
function formatDates_(colIndex) {
  // Exit if the given column index is -1, indicating
  // the column to format isn't present in the sheet.
  if (colIndex < 0)
    return; 

  // Set the date format for the date column, excluding
  // the header row.
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(2, colIndex, sheet.getLastRow() - 1, 1)
    .setNumberFormat("mmmm dd, yyyy (dddd)");
}
  1. Komut dosyası projenizi kaydedin.

Kod incelemesi

Şimdi bu iki işlevin her birindeki kodu ayrı ayrı inceleyelim:

formatDataset()

Bu işlev, daha önce uyguladığınız önceki biçim işlevlerine benzer bir kalıp izler. Öncelikle, değişkenleri etkin sayfa (sayfa) ve veri aralığı (fullDataRange) için referans içerecek şekilde alır.

İkinci olarak, sütun ve satır başlıkları hariç olmak üzere sayfadaki tüm verileri kapsayan bir aralık (noHeadersRange) oluşturmak için Range.offset(rowOffset, columnOffset, numRows, numColumns) yöntemini kullanır. Daha sonra kod, bu yeni aralığın mevcut bant genişliğinin (Range.getBandings() kullanılarak) olup olmadığını doğrular. Böyle bir durumda, Apps Kasası mevcut olan yeni şeridi eklemeye çalışırsa hata verir. Bant yoksa Range.applyRowBanding(bandingTheme, showHeader, showFooter) kullanılarak açık gri şerit eklenir. Aksi takdirde işlev devam eder.

Sonraki adımda, "release_date' etiketli sütundaki tarihleri biçimlendirmek için formatDates_(colIndex) yardımcı işlevi çağrılır (aşağıda açıklanmıştır). Sütun, daha önce uyguladığınız columnIndexOf_(colName) yardımcı işlevi kullanılarak belirtilir.

Son olarak, biçimlendirme başka bir kenarlık eklenerek biter (daha önce olduğu gibi) ve her sütun ve satır, içerdikleri verilere Sheet.autoResizeColumns(columnPosition) ve Sheet.autoResizeColumns(columnPosition) yöntemlerini kullanarak otomatik olarak yeniden boyutlandırılır.

formatDates_(colIndex)

Bu yardımcı işlev, sağlanan sütun dizinini kullanarak bir sütuna belirli bir tarih biçimi uygular. Özellikle tarih değerlerini "Ay Günü, Yıl (Haftanın Günü)" olarak biçimlendirir.

İlk olarak işlev, sağlanan sütun dizininin geçerli olduğunu (yani 0 veya daha büyük) doğrular. Aksi takdirde hiçbir şey yapmadan geri döner. Bu kontrol, örneğin sayfada"release_date'" sütununun olmaması durumunda ortaya çıkabilecek hataları önler.

Sütun dizini doğrulandıktan sonra işlev, biçimlendirmeyi uygulamak için Range.setNumberFormat(numberFormat) tuşunu kullanarak ilgili sütunu kaplayan aralığı alır (başlık satırı hariç).

Sonuçlar

Biçimlendirme işlevinizi çalışırken şunları görebilirsiniz:

  1. Henüz yapmadıysanız komut dosyası projenizi Apps Komut Dosyası düzenleyicisine kaydedin.
  2. Hızlı biçimler > Veri kümesini biçimlendir menü öğesini tıklayın.

Sonuçlar aşağıdaki gibi olacaktır:

3cfedd78b3e25f3a.gif

Başka bir biçimlendirme görevini de otomatikleştirdiniz. Artık bu biçimlendirme komutlarına sahip olduğunuza göre, bunları uygulamak için daha fazla veri ekleyelim.

7. API verilerini getirme ve biçimlendirme

Bu codelab'de şu ana kadar e-tablonuzu biçimlendirmenin alternatif bir yolu olarak Apps Komut Dosyası'nı nasıl kullanabileceğinizi gördünüz. Daha sonra, herkese açık bir API'den veri alacak, bu verileri e-tablonuza yerleştirecek ve okunabilir olması için biçimlendirecek bir kod yazacaksınız.

Son codelab'de API'den nasıl veri çekeceğinizi öğrendiniz. Burada aynı teknikleri kullanırsınız. Bu alıştırmada, e-tablonuzu doldurmak için herkese açık Star Wars API'sini (SWAPI) kullanacağız. Özellikle API'yi, orijinal üç Star Wars filminde yer alan ana karakterler hakkında bilgi edinmek için kullanırsınız.

Kodunuz API'yı çağırarak büyük miktarda JSON verisi alır, yanıtı ayrıştırır, verileri yeni bir sayfaya yerleştirir ve ardından e-tabloyu biçimlendirir.

Uygulama

Bu bölümde birkaç menü öğesi daha ekleyeceksiniz. Her menü öğesi, öğeye özgü değişkenleri ana işleve (createResourceSheet_()) geçiren sarmalayıcı komut dosyasını çağırır. Bu işlevi ve üç ek yardımcı işlevini uygularsınız. Daha önce olduğu gibi, yardımcı işlevler görevin mantıksal bölmelerini ayırmaya ve kodun okunabilir olmasına yardımcı olur.

Aşağıdaki işlemleri yapın:

  1. Apps Komut Dosyası düzenleyicisinde, komut dosyası projenizdeki onOpen() işlevini aşağıdaki şekilde güncelleyin:
/**
 * A special function that runs when the spreadsheet is opened
 * or reloaded, used to add a custom menu to the spreadsheet.
 */
function onOpen() {
  // Get the Ui object.
  var ui = SpreadsheetApp.getUi();

  // Create and add a named menu and its items to the menu bar.
  ui.createMenu('Quick formats')
    .addItem('Format row header', 'formatRowHeader')
    .addItem('Format column header', 'formatColumnHeader')
    .addItem('Format dataset', 'formatDataset')
    .addSeparator()
    .addSubMenu(ui.createMenu('Create character sheet')
                .addItem('Episode IV', 'createPeopleSheetIV')
                .addItem('Episode V', 'createPeopleSheetV')
                .addItem('Episode VI', 'createPeopleSheetVI')
                )
    .addToUi();
}
  1. Komut dosyası projenizi kaydedin.
  2. Komut dosyası düzenleyicisinde, işlevler listesinden onOpen'yi seçin ve Çalıştır'ı tıklayın. Bu işlem, eklediğiniz yeni seçeneklerle e-tablo menüsünü yeniden oluşturmak için onOpen() komutunu çalıştırır.
  3. Apps Komut Dosyası dosyası oluşturmak için Dosyalar'ın yanında, Dosya ekle dosya ekle > Script'i tıklayın.
  4. Yeni komut dosyasına "API" adını verin ve Enter tuşuna basın. (Apps Komut Dosyası, komut dosyası dosyası adına otomatik olarak bir .gs uzantısı ekler.)
  5. Yeni API.gs dosyasındaki kodu aşağıdakiyle değiştirin:
/**
 * Wrapper function that passes arguments to create a
 * resource sheet describing the characters from Episode IV.
 */
function createPeopleSheetIV() {
  createResourceSheet_('characters', 1, "IV");
}

/**
 * Wrapper function that passes arguments to create a
 * resource sheet describing the characters from Episode V.
 */
function createPeopleSheetV() {
  createResourceSheet_('characters', 2, "V");
}

/**
 * Wrapper function that passes arguments to create a
 * resource sheet describing the characters from Episode VI.
 */
function createPeopleSheetVI() {
  createResourceSheet_('characters', 3, "VI");
}

/** 
 * Creates a formatted sheet filled with user-specified
 * information from the Star Wars API. If the sheet with
 * this data exists, the sheet is overwritten with the API
 * information.
 *
 * @param {string} resourceType The type of resource.
 * @param {number} idNumber The identification number of the film.
 * @param {number} episodeNumber The Star Wars film episode number.
 *   This is only used in the sheet name.
 */
function createResourceSheet_(
    resourceType, idNumber, episodeNumber) { 
  
  // Fetch the basic film data from the API. 
  var filmData = fetchApiResourceObject_(
      "https://swapi.dev/api/films/" + idNumber);

  // Extract the API URLs for each resource so the code can
  // call the API to get more data about each individually.
  var resourceUrls = filmData[resourceType];
  
  // Fetch each resource from the API individually and push
  // them into a new object list.
  var resourceDataList = []; 
  for(var i = 0; i < resourceUrls.length; i++){
    resourceDataList.push(
      fetchApiResourceObject_(resourceUrls[i])
    ); 
  } 
  
  // Get the keys used to reference each part of data within
  // the resources. The keys are assumed to be identical for
  // each object since they're all the same resource type.
  var resourceObjectKeys = Object.keys(resourceDataList[0]);
  
  // Create the sheet with the appropriate name. It
  // automatically becomes the active sheet when it's created.
  var resourceSheet = createNewSheet_(
      "Episode " + episodeNumber + " " + resourceType);
  
  // Add the API data to the new sheet, using each object
  // key as a column header. 
  fillSheetWithData_(resourceSheet, resourceObjectKeys, resourceDataList);
  
  // Format the new sheet using the same styles the
  // 'Quick Formats' menu items apply. These methods all
  // act on the active sheet, which is the one just created.
  formatRowHeader();
  formatColumnHeader();   
  formatDataset();

}
  1. Aşağıdaki yardımcı işlevleri API.gs komut dosyası proje dosyasının sonuna ekleyin:
/** 
 * Helper function that retrieves a JSON object containing a
 * response from a public API.
 *
 * @param {string} url The URL of the API object being fetched.
 * @return {object} resourceObject The JSON object fetched
 *   from the URL request to the API.
 */
function fetchApiResourceObject_(url) {
  // Make request to API and get response.
  var response =
    UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
  
  // Parse and return the response as a JSON object.
  var json = response.getContentText();
  var responseObject = JSON.parse(json); 
  return responseObject; 
}

/** 
 * Helper function that creates a sheet or returns an existing
 * sheet with the same name.
 *
 * @param {string} name The name of the sheet.
 * @return {object} The created or existing sheet
 *   of the same name. This sheet becomes active.
 */ 
function createNewSheet_(name) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  // Returns an existing sheet if it has the specified
  // name. Activates the sheet before returning.
  var sheet = ss.getSheetByName(name);
  if (sheet) {
    return sheet.activate();
  }
  
  // Otherwise it makes a sheet, set its name, and returns it.
  // New sheets created this way automatically become the active
  // sheet.
  sheet = ss.insertSheet(name); 
  return sheet; 
}

/** 
 * Helper function that adds API data to the sheet.
 * Each object key is used as a column header in the new sheet.
 *
 * @param {object} resourceSheet The sheet object being modified.
 * @param {object} objectKeys The list of keys for the resources.
 * @param {object} resourceDataList The list of API
 *   resource objects containing data to add to the sheet.
 */
function fillSheetWithData_(
    resourceSheet, objectKeys, resourceDataList) {
  // Set the dimensions of the data range being added to the sheet.
  var numRows = resourceDataList.length;
  var numColumns = objectKeys.length;
  
  // Get the resource range and associated values array. Add an
  // extra row for the column headers.
  var resourceRange =
    resourceSheet.getRange(1, 1, numRows + 1, numColumns);
  var resourceValues = resourceRange.getValues(); 
  
  // Loop over each key value and resource, extracting data to
  // place in the 2D resourceValues array.
  for (var column = 0; column < numColumns; column++) {

    // Set the column header.
    var columnHeader = objectKeys[column];
    resourceValues[0][column] = columnHeader;
    
    // Read and set each row in this column.
    for (var row = 1; row < numRows + 1; row++) {
      var resource = resourceDataList[row - 1];
      var value = resource[columnHeader];
      resourceValues[row][column] = value;
    }
  }
  
  // Remove any existing data in the sheet and set the new values.
  resourceSheet.clear()
  resourceRange.setValues(resourceValues);
}
  1. Komut dosyası projenizi kaydedin.

Kod incelemesi

Çok fazla kod eklediniz. Nasıl yapıldığını anlamak için her bir işlevi tek tek ele alalım:

onOpen()

Quick formats menünüze birkaç menü öğesi eklediniz. Ayırıcı satırı ayarlayıp üç yeni öğe ile iç içe yerleştirilmiş menü yapısı oluşturmak için Menu.addSubMenu(menu) yöntemini kullandınız. Yeni öğeler, Menu.addItem(caption, functionName) yöntemiyle eklenir.

Sarmalayıcı işlevleri

Eklenen menü öğelerinin tümü benzer bir işlem yapıyor: SWAPI'den veri içeren bir sayfa oluşturmaya çalışıyorlar. Aradaki tek fark, her birinin farklı bir filme odaklanması.

E-tabloyu oluşturmak için tek bir işlev yazmak ve işlevin hangi filmi kullanacağını belirlemek için parametreyi kabul etmesini sağlamak pratik olur. Ancak Menu.addItem(caption, functionName) yöntemi, menü tarafından çağrıldığında parametreleri iletmenize izin vermez. Peki, aynı kodu üç kez yazmaktan nasıl kaçınabilirsiniz?

Sonuç, sarmalayıcı işlevleridir. Bunlar, belirli parametreler kullanılarak başka bir işlevi hemen çağırabileceğiniz basit işlevlerdir.

Burada kod üç sarmalayıcı işlevi kullanır: createPeopleSheetIV(), createPeopleSheetV() ve createPeopleSheetVI(). Menü öğeleri bu işlevlere bağlıdır. Bir menü öğesi tıklandığında, sarmalayıcı işlevi yürütülür ve hemen menü öğesi için uygun parametreleri ileterek ana sayfa oluşturucu işlevini createResourceSheet_(resourceType, idNumber, episodeNumber) çağırır. Bu durumda, e-tablo oluşturucu işlevinden, Star Wars filmlerinden birinin ana karakter verileriyle doldurulan bir sayfa oluşturmasını isteyebilirsiniz.

createResourceSheet_(resourceType, idNumber, episodeNumber)

Bu, bu alıştırmada ana sayfa oluşturucu işlevidir. Bazı yardımcı işlevlerin yardımıyla API verilerini alır, ayrıştırır, bir sayfa oluşturur, API verilerini sayfaya yazar ve ardından önceki bölümlerde oluşturduğunuz işlevleri kullanarak sayfayı biçimlendirir. Ayrıntıları inceleyelim:

İlk olarak işlev, temel film bilgilerini almak üzere API isteğinde bulunmak için fetchApiResourceObject_(url) kullanır. API yanıtı, filmlerden belirli kişiler (burada kaynaklar olarak bilinir) hakkında daha fazla bilgi edinmek için kodun kullanabileceği URL'lerin bir koleksiyonunu içerir. Kod, tümünü resourceUrls dizisinde toplar.

Ardından kod, resourceUrls içindeki her kaynak URL'si için API'yi çağırmak üzere tekrar tekrar fetchApiResourceObject_(url) kullanır. Sonuçlar resourceDataList dizisinde depolanır. Bu dizinin her öğesi, filmden farklı bir karakteri açıklayan bir nesnedir.

Kaynak veri nesnelerinde, ilgili karakter hakkındaki bilgilerle eşlenen birkaç ortak anahtar bulunur. Örneğin, "name' tuşu, filmdeki karakterin adıyla eşleşir. Ortak veri yapılarını kullanmaları amaçlandığından, her kaynak veri nesnesinin anahtarlarının tamamen aynı olduğunu varsayarız. Daha sonra anahtar listesi ihtiyaç duyulduğundan kod, JavaScript Object.keys() yöntemini kullanarak anahtar listesini resourceObjectKeys içinde saklar.

Ardından oluşturucu işlevi, yeni yardımcı verilerin yerleştirileceği sayfayı oluşturmak için createNewSheet_(name) yardımcı işlevini çağırır. Bu yardımcı işlev çağrıldığında yeni sayfa da etkinleştirilir.

Sayfa oluşturulduktan sonra sayfaya tüm API verilerini eklemek için fillSheetWithData_(resourceSheet, objectKeys, resourceDataList) yardımcı işlevi çağrılır.

Son olarak, daha önce oluşturduğunuz tüm biçimlendirme işlevleri, aynı biçimlendirme kurallarını yeni verilere uygulamak için çağrılır. Yeni sayfa etkin sayfa olduğu için kod, değiştirmeden bu işlevleri yeniden kullanabilir.

fetchApiResourceObject_(url)

Bu yardımcı işlev, önceki codelab Verilerle çalışma özelliğinde kullanılan fetchBookData_(ISBN) yardımcı işlevine benzer. Belirtilen URL'yi alır ve yanıt almak için UrlFetchApp.fetch(url, params) yöntemini kullanır. Ardından yanıt, HTTPResponse.getContextText() ve JavaScript JSON.parse(json) yöntemleri kullanılarak bir JSON nesnesine ayrıştırılır. Ortaya çıkan JSON nesnesi döndürülür.

createNewSheet_(name)

Bu yardımcı işlev oldukça basittir. Öncelikle, e-tabloda belirtilen ada sahip bir sayfanın olup olmadığını doğrular. İşaretlerse işlev, sayfayı etkinleştirir ve döndürür.

E-tablo mevcut değilse işlev sayfayı Spreadsheet.insertSheet(sheetName) ile oluşturur, etkinleştirir ve yeni sayfayı döndürür.

fillSheetWithData_(resourceSheet, objectKeys, resourceDataList)

Bu yardımcı işlev, yeni e-tablonun API verileriyle doldurulmasından sorumludur. Parametre olarak yeni sayfayı, nesne anahtarlarının listesini ve API kaynak nesnelerini parametre olarak alır. Her nesne anahtarı yeni sayfadaki bir sütunu ve her kaynak nesnesi bir satırı temsil eder.

İşlev önce yeni API verilerini sunmak için gereken satır ve sütun sayısını hesaplar. Bu, sırasıyla kaynak ve anahtar listesinin boyutudur. İşlev, daha sonra verilerin yerleştirileceği bir çıkış aralığı (resourceRange) tanımlar ve sütun başlıklarını tutmak için ek bir satır ekler. resourceValues değişkeni, resourceRange öğesinden alınan bir 2D değer dizisi tutar.

İşlev, daha sonra objectKeys listesindeki her nesne anahtarının üzerine döner. Anahtar, sütun başlığı olarak ayarlanır ve ardından her kaynak nesnesinden ikinci bir döngü geçer. Her bir satır (satır, sütun) çifti için, ilgili API bilgileri resourceValues[row][column] öğesine kopyalanır.

resourceValues doldurulduktan sonra, önceki menü öğesi tıklamalarından elde edilen verileri içerebilmesi için hedef sayfa Sheet.clear() kullanılarak temizlenir. Son olarak, yeni değerler sayfaya yazılır.

Sonuçlar

Çalışmanızın sonuçlarını aşağıdakileri yaparak görebilirsiniz:

  1. Henüz yapmadıysanız komut dosyası projenizi Apps Komut Dosyası düzenleyicisine kaydedin.
  2. Hızlı biçimler > Karakter sayfası oluştur > Bölüm IV menü öğesini tıklayın.

Sonuçlar aşağıdaki gibi olacaktır:

d9c472ab518d8cef.gif

Artık verileri E-Tablolar'a aktarmak ve otomatik olarak biçimlendirmek için kod yazdınız.

8. Sonuç

Tebrikler, bu codelab'i tamamladınız. Apps Komut Dosyası projelerinize ekleyebileceğiniz E-Tablolar biçimlendirme seçeneklerinden bazılarını görüp, büyük bir API veri kümesini içe aktarıp biçimlendiren etkileyici bir uygulama oluşturdunuz.

Bu codelab'i faydalı buldunuz mu?

Evet Hayır

Öğrendikleriniz

  • Apps Komut Dosyası ile çeşitli E-Tablolar biçimlendirme işlemlerini uygulama.
  • onOpen() işleviyle alt menü oluşturma.
  • Apps Komut Dosyası ile, getirilen JSON nesnelerinin listesini yeni bir veri sayfasına biçimlendirme.

Sonraki adımlar

Bu oynatma listesindeki bir sonraki codelab'de, grafikteki verileri görselleştirmek ve grafikleri Google Slaytlar sunularına aktarmak için Apps Komut Dosyası'nın nasıl kullanılacağı gösterilmektedir.

Bir sonraki codelab'i Slaytlar'da veri grafiği oluşturma ve gösterme bölümünde bulabilirsiniz.