Dönüştürülen kodunuzdaki hataları düzeltme

Makro Dönüştürücü eklentisi, dönüşüm işleminin büyük kısmını otomatikleştirir. Ancak kodunuza son halini vermek için bazı API'lerde ve diğer öğelerde ayarlamalar yapmanız gerekebilir.

Projenize eklenen Apps Komut Dosyası dosyalarını (GS dosyaları) anlamak, farklı hata türlerini yorumlamak ve hataların nasıl düzeltileceğini öğrenmek için bu kılavuzu kullanın.

Projenize eklenen Apps Komut Dosyası dosyalarını anlama

Aşağıdaki konularda yardımcı olmak için Apps Komut Dosyası projenize ek GS dosyaları eklenir:

  • Apps Komut Dosyası'nda bulunmayan VBA sabitlerini ve değerlerini tanımlayın.
  • Dönüştürülmemiş API'leri uygulayın.
  • Varyantları çözümleyin.

Aşağıdaki GS dosyaları Apps Komut Dosyası projenize eklenir:

  • Library.gs
  • Unimplemented_constructs.gs
  • Variant_resolutions.gs

Library.gs

Genel olarak, library.gs dosyasındaki hiçbir şeyi değiştirmenize gerek yoktur.

library.gs dosyası, VBA kodunuzda kullanılan ve Apps Komut Dosyası'nda bulunmayan işlevleri ve sabitleri tanımlar. Bu, yeni Apps Komut Dosyası kodunun VBA kodunuza daha iyi benzemesini sağlar. Ayrıca, library.gs dosyasındaki işlevler veya sabit değerler her kullanıldığında tanımları tekrarlamanız gerekmez.

Unimplemented_constructs.gs

unimplemented_constructs.gs dosyası, Makro Dönüştürücü tarafından dönüştürülemeyen yapıları veya API'leri ele alır. Kodunuzun gerektiği gibi çalışması için muhtemelen bu dosyayı değiştirmeniz gerekir.

Örnek: Window.Activate()

Aşağıda, Window.Activate() adında desteklenmeyen bir API örneği verilmiştir. Makro Dönüştürücü, benzer bir adla yeni bir Apps Komut Dosyası işlevi oluşturur ve bunu unimplemented_constructs.gs dosyasında tanımlar. VBA işlevi desteklenmediğinden, yeni Apps Komut Dosyası işlevi için bir istisna söz konusudur.

Yeni işlev, VBA kodunda orijinal API'nin kullanıldığı her yerde dönüştürülmüş Apps Komut Dosyası koduna eklenir.

Orijinal API'nin davranışını yeniden oluşturmaya yönelik bir geçici çözüm bulursanız yalnızca unimplemented_constructs.gs dosyasındaki işlevin tanımını güncellemeniz gerekir. İşlev burada tanımlandıktan sonra, işlevin Apps Komut Dosyası projenizde göründüğü her yerde geçerli olur.

Koddaki örneği aşağıda bulabilirsiniz:

Orijinal VBA kodu

Window.activate()

Dönüştürülen Apps Komut Dosyası kodu, satır içi olarak eklenir

_api_window_activate();

unimplemented_constructs.gs dosyasına işlev tanımı eklendi

/**
 * Could not convert window.activate API. Please add relevant code in the
 * following function to implement it.
 * This API has been used at the following locations in the VBA script.
 *     module1 : line 3
 *
 * We couldn't find an equivalent API in Apps Script for this VBA API. Please
 * reconsider if this function call is critical, otherwise consider implementing
 * it in a different way.
 */
function _api_window_activate(CallingObject) {
  ThrowException("API window.activate not supported yet.");
}

Variant_resolutions.gs

Bir nesnenin türü belirlenemezse variant_resolutions.gs dosyası Apps Komut Dosyası projenize eklenir. Bu durum, bir API'nin birden fazla dönüş türüne sahip olması veya nesnenin kendisinin bir varyantın kendisi olarak bildirilmesi gibi birden çok nedenden kaynaklanabilir.

Makro Dönüştürücü, bu dosyaya söz konusu API'nin yerini alan ve nesne türünün belirlenmesine yardımcı olan __handle_resolve_<api>() adlı yeni bir işlev ekler.

Bazı durumlarda, nesne türünü manuel olarak bildirmek için __handle_resolve_<api>() işlevini güncellemeniz gerekebilir. Desteklenmeyen nesne türü bölümüne bakın.

Örnek: name()

VBA'daki birçok nesne türü bir name() API'sini tanımlar. Genellikle Apps Komut Dosyası eşdeğeri getName() olsa da her nesne türü için geçerli değildir. Birden çok alternatif durum olabilir:

  • Nesnenin eşdeğer API'sine getName() dışında bir ad verilmiş.
  • Nesnenin adını alacak bir Apps Komut Dosyası API'si yok.
  • Eşdeğer bir Apps Komut Dosyası nesnesi yok.

Nesne türü belirlenmediğinde, Makro Dönüştürücü, variant_resolutions.gs dosyasında __handle_resolve_name adlı yeni bir işlev oluşturur.

Koddaki örneği aşağıda bulabilirsiniz:

Orijinal VBA kodu

a = Selection.name

Bu durumda, name() API'si mevcut seçimde çağrılır. Seçim bir E-Tablo veya Şekil nesnesi olabilir. E-tablo nesnesiyse çeviri getName() olur, ancak Şekil nesnesiyse Apps Komut Dosyası'nda bunun eşdeğeri yoktur.

Dönüştürülen Apps Komut Dosyası kodu, satır içi olarak eklenir

a = __handle_resolve_name({}, getActiveSelection(), {});

Farklı nesne türlerini çözmek için aşağıdaki __handle_resolve_name() işlevi variant_resolution.gs dosyasına eklendi. İşlev, nesne türünü kontrol eder, destekleniyorsa getName() değerini kullanır veya getName() desteklenmiyorsa hata verir.

variant_resolution.gs dosyasına işlev tanımı eklendi

function __handle_resolve_name(ExecutionContext, CallingObject, params_map) {
  var found_api_variant = false;
  var return_value;
  if (String(CallingObject) == "Sheet") {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (CallingObject instanceof ChartInSheet) {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (!found_api_variant) {
    ThrowException("API .name not supported yet.");
  }
  return return_value;
}

Hataları bul

Dönüştürülen Apps Komut Dosyası kodunda bir hatayla karşılaştığınızda, mesajda hatanın türü ve konumu belirtilir. Hata mesajının biçimi, hangi Apps Komut Dosyası çalışma zamanını kullandığınıza bağlı olarak farklılık gösterir.

Varsayılan V8 çalışma zamanındaysanız aşağıdaki gibi bir hata görürsünüz:

_api_windows_active (unimplemented_constructs:2:3)

Bu, hatanın unimplemented_constructs.gs dosyasında, satır 2, karakter 3'te bulunduğu anlamına gelir.

Kullanımdan kaldırılan Rhino çalışma zamanındaysanız aşağıdaki gibi bir hata görürsünüz:

unimplemented_constructs:2 (_api_windows_active)

Bu, hatanın unimplemented_constructs.gs dosyasının 2. satırında bulunduğu anlamına gelir.

Hata Türleri

Yukarıda açıklanan unimplemented_constructs.gs ve variant_resolution.gs dosyalarında karşılaştığınız hataların çoğunu düzeltebilirsiniz.

Karşılaşabileceğiniz hata türleri şunlardır:

Uygulanmamış API

Uygulanmayan API, Macro Converter'ın VBA'dan Apps Komut Dosyası'na dönüştüremediği bir API'dir ve bu API için bilinen bir geçici çözüm yoktur.

Uygulanmamış API'ler genellikle unimplemented_constructs.gs dosyasına boş işlevler (bazen boş imzalarla) olarak eklenir. Nesne türü belirlenemezse uygulanmayan API bunun yerine variant_resolution.gs dosyasına eklenebilir.

Dönüşümden önce oluşturduğunuz uyumluluk raporunda bu API, Daha fazla inceleme gerekiyor şeklinde etiketlenir.

Dosyanızı dönüştürmeden önce VBA kodunuzda bu tür API'yi düzeltmezseniz Apps Komut Dosyası projesinde aşağıdaki gibi görünür:

/**
* Could not convert . Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*      : 
* We couldn't find an equivalent API in Apps Script for this VBA API. Please
* reconsider if this function call is critical, otherwise consider implementing
* it in a different way.
* @param param1 {}
* @param param2 {}
* ...
* @return {}
*/
function _api_(param1, param2, ....) {
  ThrowException("API  not supported yet.");
}

Uygulanmayan API hatalarını düzeltme

Henüz uygulanmamış API'yi mevcut Apps Komut Dosyası API'leri veya JS kitaplıklarıyla tanımlayın. Bu işlemi gerçekleştirmek için aşağıdaki adımları uygulayın:

  1. Hatanın bulunduğu yerde, dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümünü inceleyin.
  2. İşlevin üstünde, eklenen yorumu okuyun. Bazı durumlarda yorum, API'nin Apps Komut Dosyası'nda nasıl uygulanacağını önerir.
  3. API'yi Apps Komut Dosyası'nda uygulamanın yolunu bulamıyorsanız kodunuzdan kaldırabilirsiniz.
  4. Geçici bir çözüm bulamıyor veya bu API'yi kodunuzdan kaldırıyorsanız ve makronuz bu hatayı veriyorsa bu makroyu dönüştüremezsiniz.

Uygulanmamış API hatası örnekleri

Aşağıda, uygulanmamış API senaryolarına örnekler ve bunların nasıl düzeltileceği açıklanmıştır:

  • Eşdeğer Apps Komut Dosyası yok: Apps Komut Dosyası'nda bulunmayan bir API olan Chart.Protect için dolaylı bir geçici çözümü gösterir.
  • Bilinmeyen nesne türü: Değişken olan bir nesne türünün nasıl işleneceğini ve Apps Komut Dosyası'nda yeniden oluşturulabilecek desteklenmeyen bir nesne türünün nasıl uygulanacağını gösterir.
1. Örnek: Eşdeğer Apps Komut Dosyası veya bilinmeyen API yok

Bu örnekte, Google E-Tablolar'da bir grafiği korumanın bir yolu olmadığından Chart.Protect otomatik olarak dönüştürülmemiştir.

/**
* Could not convert chart.protect API. Please add relevant code in the following
* function to implement it.
*
* This API has been used at the following locations in the VBA script.
*     sheet1 : line 3
* You can use the following Apps Script APIs to convert it.
*
* Comments : Auto conversion of Chart.Protect is not supported yet. If the API is
* critical for the workflow the user can implement the unimplemented handler
* method in the generated code, else comment out the throw statement.
*
* @param {Object} CallingObject represents the parent object using which the API
* has been called.
* @param {string} Password
* @param {boolean} DrawingObjects
* @param {boolean} Contents
* @param {boolean} Scenarios
* @param {boolean} UserInterfaceOnly
*
*/
function _api_chart_protect(
   CallingObject, Password, DrawingObjects, Contents, Scenarios,
   UserInterfaceOnly) {
 ThrowException('API chart.protect not supported yet.');
}
Bir grafiği koruyamasanız bile verilerin değiştirilmemesini sağlamak için grafiğin veri aralığını koruyabilirsiniz.

Aralığı korumayla ilgili bir örnek aşağıda gösterilmiştir:
/**
* Could not convert chart.protect API. Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*     sheet1 : line 3
*
* You can use the following Apps Script APIs to convert it.
* Comments : Auto conversion of Chart.Protect is not supported yet. If the API
* is critical for the workflow the user can implement the unimplemented handler
* method in the generated code, else comment out the throw statement.
*
* @param {Object} CallingObject represents the parent object using which the API
* has been called.
* @param {string} Password
* @param {boolean} DrawingObjects
* @param {boolean} Contents
* @param {boolean} Scenarios
* @param {boolean} UserInterfaceOnly
*/
function _api_chart_protect(
  CallingObject, Password, DrawingObjects, Contents, Scenarios, UserInterfaceOnly) {
var ranges = CallingObject.getChart().getRanges();
for (var i = 0; i < ranges.length; i++) {
  // Note that this does not lock the range for the document owner.
  ranges[i].protect();
}
}
2. Örnek: Desteklenmeyen nesne türü

Nesne türü bilinmiyorsa uygulanmayan API hatası variant_resolution.gs dosyasına eklenir. Aşağıdaki örnek, yukarıdaki VBA name() API örneğinin kapsamını genişletmektedir. variant_resolution.gs başlıklı makaleyi inceleyin.

Bu örnekte şunları öğreneceksiniz:

  1. name() API'nin, variant_resolution.gs dosyasında yeni bir işleve dönüştürülmesi.
  2. Yeni işlevin, dönüştürülmüş kodda çağrılma şekli.
  3. Apps Komut Dosyası'nda desteklenmeyen bir nesne türü olan CommandBar için geçici çözüm oluşturma.

1. Dönüştürülen kod, name() işlevinin çağrıldığı nesne türünü tam olarak belirleyemediğinden, Makro Dönüştürücü, aşağıda gösterilen __handle_resolve_name adında yeni bir işlev oluşturur.

function __handle_resolve_name(ExecutionContext, CallingObject, params_map) {
 var found_api_variant = false;
 var return_value;
  if (String(CallingObject) == "Sheet") {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (CallingObject instanceof ChartInSheet) {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (!found_api_variant) {
    ThrowException('API .name not supported yet.');
  }
  return return_value;
}

2. VBA kodunun name() API'yi çağıran bir PrintName() işlevini tanımladığını varsayalım. VBA kodu aşağıda gösterilir:

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
"name()" değişken olan bir nesnede çağrıldığından, dönüştürülen kod, dönüşüm sırasında nesne türünü bilmez. Dönüştürülen Apps Komut Dosyası kodu, "__handle_resolve_name" işlevini çağırır:
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

3. VBA kodunuzun CommandBar nesne türünde PrintName() işlevini çağırdığını varsayalım. VBA kodu aşağıda gösterilir:

PrintName Application.CommandBars.item("Standard")
CommandBar, Apps Komut Dosyası'nda desteklenmez. Bu nedenle, yukarıdaki VBA kodunda kullanılan iki yöntem de desteklenmez.
  • Application.CommandBars(): VBA'da bu, CommandBar nesnenin tümünün listesini döndürür.
  • CommandBars.item(): VBA'da bu, belirli bir CommandBar nesnesi döndürür.
Bu nesne türü Apps Komut Dosyası'nda desteklenmediği için dönüştürülen kod, "unimplemented_structs.gs" dosyasında tanımlamanız gereken aşağıdaki işlevleri oluşturur.
  • _api_application_commandbars()
  • _api_commandbars_item()
İşlevler, dönüştürülmüş kodda aşağıda gösterildiği gibi çağrılır:
PrintName(_api_commandbars_item(_api_application_commandbars(), "Standard")))

Here’s how the new functions are added to the unimplemented_construct.gs file:

function _api_application_commandbars(CallingObject) {
  ThrowException('API application.commandbars not supported yet.');
}
function _api_commandbars_item(CallingObject, index) {
  ThrowException('API commandbars.item not supported yet.');
}

Yeni işlevlerin çalışmasını sağlamak için aşağıdaki adımları uygulayın:

3.1 CommandBars işlevlerini oluşturan yeni bir nesne türü ve VBA'dakine benzer yeni bir CommandBars koleksiyonu tanımlayın.

3.2 Yeni nesne türü için bir getName() yöntemi ekleyin.

Adım 3.1 ve 3.2 aşağıdaki kodda gösterilmiştir. Menü nesneleri, CommandBars davranışını taklit eden yeni bir nesne türü olarak oluşturulur.

// Our Implementation of CommandBar using Menu objects.

function CommandBar(name) {
  this.name = name;
  // Create a menu object to represent the commandbar.
  this.menu = SpreadsheetApp.getUi().createMenu(name);
  // Create methods for retrieving or updating the name of the object
  this.getName = function() {
    return this.name;
  };
  this.updateName = function(name) {
    this.name = name;
  };
  // ========================================================================
  // Implement other methods of CommandBar objects that are used in the script.
  // =====================================================================
  return this;
}
// Our implementation of the collection of CommandBars that exists in VBA
function CommandBars() {
  this.commandBars = [];
  this.getCommandBar = function(name) {
    for (var i = 0; i < this.commandBars.length; i++) {
      if (!this.commandBars[i].getName() == name) {
        return this.commandBars[i];
      }
    }
    // No commandBar with the name exists, create a new one and return.
    var commandBar = new CommandBar(name);
    this.commandBars.push(commandBar);
    return commandBar;
  };
  return this;
}
// Create a global object that represents CommandBars collection.
var GlobalCommandBars = new CommandBars();

3.3 Yeni nesne türünü işlemek için variant_resolution.gs dosyasındaki __handle_resolve_name işlevini değiştirin. İşleve aşağıdaki gibi bir bölüm ekleyin:

function __handle_resolve_name(ExecutionContext, CallingObject, params_map) {
 var found_api_variant = false;
 var return_value;
 if (String(CallingObject) == "Sheet") {
   if (!ExecutionContext.isLhs) {
     return_value = CallingObject.getName();
     found_api_variant = true;
   }
 }
 if (CallingObject instanceof ChartInSheet) {
   if (!ExecutionContext.isLhs) {
     return_value = CallingObject.getName();
     found_api_variant = true;
   }
 }
 // New section added below
 // ========================================================================
 if (CallingObject instanceof CommandBar) {
   objectExtend(params_map, {VALUETOSET: params_map.param0});
   if (ExecutionContext.isLhs) {
     // Call the setter method.
     CallingObject.updateName(params_map.VALUETOSET);
     found_api_variant = true;
   } else {
     // Getter is called, return the commandbar name,
     return_value = CallingObject.getName();
     found_api_variant = true;
   }
 }
 // ========================================================================
 // New section added above
 if (!found_api_variant) {
   ThrowException('API .name not supported yet.');
 }
 return return_value;
}

3.4 unimplemented_constructs.gs dosyasında oluşturulan iki işlevi tanımlayın (_api_application_commandbars(), _api_commandbars_item()). Bu adım, fonksiyona ait orijinal çağrıların çalışmasını sağlar.

//This is straightforward based on the implementation of a CommandBar and the
// CommandBars collection above:
function _api_application_commandbars(CallingObject) {
 return GlobalCommandBars;
}
function _api_commandbars_item(CallingObject, index) {
 return CallingObject.getCommandBar(index);
}

Uygulanmamış dil yapıları

construct, yürütme akışını veya veri görüntülemeyi kontrol eden kod dili öğesidir. Örneğin döngüler, etiketler, etkinlikler ve gotos'lar. Tüm VBA yapılarının listesini burada bulabilirsiniz.

Makro Dönüştürücü'nün dönüştüremediği yapılar, uygulanmayan dil yapıları olarak kabul edilir.

Makro Dönüştürücü, uygulanmamış bir dil yapısının mevcut olduğunu belirlediğinde, bir TODO yorumu ekler.

Aşağıdaki VBA yapıları desteklenmez:

Uygulanmayan dil yapısı hatalarını düzeltme

  1. Kodunuzu, mantığınızın desteklenmeyen dil yapısına dayanmayacak şekilde güncelleyin.
  2. Hatanın bulunduğu yerde, dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümünü inceleyin.
  3. Kodun mantığına göre kodu, desteklenmeyen dil yapısını gerektirmeyecek şekilde güncelleyin.
  4. Desteklenmeyen dil yapısı olmadan kodunuzu yeniden yazmanın bir yolunu bulamıyorsanız bu makroyu dönüştüremezsiniz.

Uygulanmamış dil yapısı hatalarına örnekler

GoTo ifadesi, en yaygın uygulanmamış dil yapılarından biridir. Bazı VBA GoTo ifadelerini döngülerle değiştirebilirsiniz. Aşağıda, GoTo ifadeleri yerine döngü kullanımına dair iki örnek verilmiştir.

1. Örnek: GoTo değerini While Loop ile değiştirin

Orijinal VBA kodu
Sub Test()
 a = 0
 start: Debug.Print a
 While a < 100
   a = a + 1
   If a Mod 3 == 0
     Goto start
   End If
 Wend
End Sub
Eşdeğer Apps Komut Dosyası kodu
function test() {
 var a = 0;
 start: do {
   console.log(a);
   while (a < 100) {
     a = a + 1;
     if (a % 3 == 0) {
       continue start;
     }
   }
   break start;
 } while (true);
}

2. Örnek: GoTo değerini Loop için olarak değiştirin

Orijinal VBA kodu
Sub Test()
 a = 0
 For i = 1 to 100
   For j = 1 to 10
     a =a a + 1
     If i + j > 50
       GoTo endLoop
     End If
   Next j
 Next i
 endLoop: MsgBox a
End Sub
Eşdeğer Apps Komut Dosyası kodu
function test() {
 var a = 0;
 endLoop: for (var i = 1; i <= 100; i++) {
    for  (var j = 0; j <=10; j++) {
      If (i + j > 50) {
        break endLoop;
      }
    }
 }
 Browser.msgBox(a);
}

   break start;
 } while (true);
}

Kısmen desteklenen API

Kısmen desteklenen API'ler için bazı giriş parametreleri Apps Komut Dosyası'nda desteklenirken, bazıları desteklenmez.

Örneğin VBA API legend_position, Excel grafiğinde göstergeyi tanımlamak için kullanılır. Aşağıdakiler de dahil olmak üzere birden fazla giriş değeri türünü destekler:

  • xlLegendPositionBottom: Göstergeyi grafiğin en altına yerleştirir.
  • xlLegendPositionCorner: Göstergeyi grafiğin köşesine yerleştirir.
  • xlLegendPositionCustom: Göstergeyi grafikte özel konumlara yerleştirir.

Apps Komut Dosyası'nda bu değerlerin yalnızca bazılarını destekleyen eşdeğer bir kod vardır. Aşağıdaki değerler desteklenmez:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

Dönüştürülmüş kodunuzda kısmen desteklenen API'lerin desteklenmeyen değerlerini işaretlemek için bu değerleri kontrol eden library.gs dosyasına bir doğrulama koşulu eklenir. Örneğin:

if (position == xlLegendPositionCorner ||
     position == xlLegendPositionCustom) {
   position = _handle_legend_position_error(position);
}

Doğrulama koşulu, desteklenmeyen değerlerden birini bulursa unimplemented_constructs.gs dosyasında bir hata işleyici işlevi (_handle_<API_name>_error) oluşturulur.

İşlev, bir kullanıcı hatası bildirir ve değeri, desteklenen bir değerle değiştirmez. Örneğin:

/**
* Throw error message for unsupported legend position.
* The VBA API Legend.Position which can take values xlLegendPositionTop,
* xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight,
* xlLegendPositionCorner, xlLegendPositionCustom. It is partially supported in
* Apps Scripts that supports only a subset of the values (does not support
* xlLegendPositionCorner and xlLegendPositionCustom).
* @param {string} position
*/
function _handle_legend_position_error(position) {
// Please comment the throw statement and return a supported position value
// instead.
// Values that are supported here are xlLegendPositionTop,
// xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight.
throw new Error(
   'Google Sheets does not support legend position: ' + position);
}

Kısmen desteklenen API hatalarını düzeltme

Desteklenmeyen değerleri ihtiyaçlarınız için kabul edilebilir bir geçici çözümle değiştirmek üzere _handle_<API_name>_error işlevini tanımlayın.

  1. Hatanın bulunduğu yerde, dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümünü inceleyin.
  2. Hangi değerlerin desteklenip hangilerinin desteklenmediğini anlamak için işlevin üzerindeki yorumu okuyun.
  3. Desteklenmeyen değerler için hangi desteklenen değerlerin uygun bir alternatif olarak değerlendirilebileceğini belirleyin.
  4. Bunun yerine, desteklenen bir değer döndürecek şekilde _handle_<API_name>_error işlevini güncelleyin.
  5. Desteklenmeyen değeri değiştirmenin bir yolunu bulamıyorsanız bu makroyu dönüştüremezsiniz.

Kısmen desteklenen API hatası örneği

Aşağıdaki örnek, yukarıda bahsedilen legend_position VBA API'sini kapsar. Kısmen desteklenen API başlıklı makaleyi inceleyin.

Aşağıda, desteklenmeyen bir değer (xlLegendPositionCustom) kullanan orijinal VBA kodu örneğini bulabilirsiniz.

Charts(1).Legend.Position = xlLegendPositionCustom

Makro Dönüştürücü, unimplemented_constructs.gs dosyasına aşağıdaki işlevi ekler:

/**
* Throw error message for unsupported legend position.
* The VBA API Legend.Position which can take values xlLegendPositionTop,
* xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight,
* xlLegendPositionCorner, xlLegendPositionCustom. It is partially supported in
* Apps Scripts that supports only a subset of the values (does not support
* xlLegendPositionCorner and xlLegendPositionCustom).
* @param {string} position
*/
function _handle_legend_position_error(position) {
// Please comment the throw statement and return a supported position value
// instead.
// Values that are supported here are xlLegendPositionTop,
// xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight.
throw new Error(
   'Google Sheets does not support legend position: ' + position);
}

Manuel işlem gerekiyor

Manuel işlem yapılması gerekir, VBA API'nin Apps Komut Dosyası'na dönüştürülebileceği anlamına gelir ancak bunun için geçici bir çözüm gerekir.

Dönüşümden önce oluşturduğunuz uyumluluk raporunda bu API türü, Geçici çözümlerle destekleniyor şeklinde etiketlenir.

Dosyanızı dönüştürmeden önce VBA kodunuzda bu tür API'yi düzeltmezseniz Apps Komut Dosyası projesinde aşağıdaki gibi görünür:

/**
* Could not convert  API. Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*      : 
*
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : 
* Apps Script documentation links : 
*
* @param param1 {}
* @param param2 {}
* ...
* @return {}
*/
function _api_(param1, param2, ....) {
 ThrowException("API  not supported yet.");
}

Manuel işlem gerektiren hataları düzeltme

API'nin amaçlandığı şekilde çalışmasını sağlamak için API'ye ilişkin geçici bir çözüm uygulayın. 1. Hatanın bulunduğu yerde, dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümüne bakın. 1. Geçici bir çözüm olarak hangi API'lerin kullanılabileceğini anlamak için işlevin üzerindeki yorumu okuyun. 1. Uygun bir geçici çözüm bulamıyorsanız API'yi kodunuzdan kaldırmayı düşünün. 1. Geçici bir çözüm bulamıyor veya bu API'yi kodunuzdan kaldırıyorsanız ve makronuz hata veriyorsa bu makroyu dönüştüremezsiniz.

Manuel çalışma gerektiren hataların örnekleri

Manuel çalışma gerektiren hatalara neden olan API'lere ve bu hataların nasıl düzeltileceğine dair örnekleri burada bulabilirsiniz:

1. örnek: Autocorrect.Addreplacement

Aşağıdaki örnekte Autocorrect.Addreplacement VBA API'si dönüştürülebilir, ancak bunun için geçici bir çözüm uygulanması gerekir. Makro Dönüştürücü, kod yorumlarında işlevin nasıl uygulanacağını önerir.

/**
* Could not convert autocorrect.addreplacement API. Please add relevant code in
* the following function to implement it.
* This API has been used at the following locations in the VBA script.
*     sheet1 : line 3
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : FindReplaceRequest , onEdit
* Apps Script documentation links :
* https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* https://developers.google.com/sheets/api/eap/reference/rest/v4/spreadsheets/request?hl=en#findreplacerequest

* Comments : AutoCorrect.AddReplacement was not converted, but there is an
* equivalent option you can implement manually. Use onEdit and FindReplaceRequest
* APIs instead, see https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* and https://developers.google.com/sheets/api/eap/reference/rest/v4/spreadsheets/request?hl=en#findreplacerequest.
* For more information on API manual implementation, see
* https://developers.google.com/apps-script/guides/macro-converter/fix-conversion-errors.

* @param {Object} CallingObject represents the parent object using which the API
* has been called.
* @param {string} What
* @param {string} Replacement
* @return {string}
*/

function _api_autocorrect_addreplacement(CallingObject, What, Replacement) {
  ThrowException('API autocorrect.addreplacement not supported yet.');

}

Autocorrect.Addreplacement API'nin uygulanması aşağıda gösterilmiştir:

var AUTO_CORRECTIONS = "AUTO_CORRECTIONS";
// Need to get the autocorrections set in previous sessions and use them.
var savedAutoCorrections = PropertiesService.getDocumentProperties().getProperty(AUTO_CORRECTIONS);
var autoCorrections = savedAutoCorrections ? JSON.parse(savedAutoCorrections) : {};
function onEdit(e) {
autoCorrect(e.range);
}
function autoCorrect(range) {
for (key in autoCorrections) {
// Replace each word that needs to be auto-corrected with their replacements.
range.createTextFinder(key)
.matchCase(true)
.matchEntireCell(false)
.matchFormulaText(false)
.useRegularExpression(false)
.replaceAllWith(autoCorrections[key]);
}
}
/**
* Could not convert autocorrect.addreplacement API. Please add relevant code in
* the following function to implement it.
* This API has been used at the following locations in the VBA script.
* sheet1 : line 3
*
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : createTextFinder , onEdit
* Apps Script documentation links : https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit ,
createTextFinder
* Comments : AutoCorrect.AddReplacement was not converted, but there is an
* equivalent option you can implement manually. Use onEdit and FindReplaceRequest
* APIs instead, see https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* and createTextFinder. For more information on API manual implementation, see
* https://developers.google.com/apps-script/guides/macro-converter/fix-conversion-errors.
*
* @param {Object} CallingObject represents the parent object using which the API has been called.
* @param {string} What
* @param {string} Replacement
*
* @return {string}
*/

function _api_autocorrect_addreplacement(CallingObject, What, Replacement) {
autoCorrections[What] = Replacement;
// Store the updated autoCorrections in the properties so that future executions use the correction.
PropertiesService.getDocumentProperties().setProperty(AUTO_CORRECTIONS, JSON.stringify(autoCorrections));
}

2. Örnek: Workbook.open()

VBA API'si workbook.open(), dosya yolunu temel alan yerel bir dosyayı açar.

VBA kodunda workbook.open() tarafından açılan iki dosya olduğunu varsayalım:

  • 1. dosya: C:\Data\abc.xlsx
  • 2. Dosya: C:\Data\xyz.xlsx

Aşağıda, Makro Dönüştürücü'nün, Workbook.open() ürününün, Dosya 1'i açmak için kullanıldığı her yerde Workbook.open() yerine Apps Komut Dosyası'yla nasıl değiştirildiği gösterilmektedir:

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
Apps Komut Dosyası projesindeki unimplemented_constructs.gs dosyasına aşağıdaki hata eklenir:
/**
* Method to return the spreadsheet id manually.
*
* @param {string} FileName ID of the spreadsheet to be opened.
* @return {string} return the spreadsheet id.
*/
function _handle_mso_excel_get_google_spreadsheet_id(FileName) {
 // Upload the Excel files being opened by the API to Google Drive and convert
 // them to Google Sheets.
 // Determine the spreadsheet ID of the Google Sheets file created.
 // Implement this method to return the corresponding spreadsheet ID when given
 //the original file path as parameter.
 throw new Error('Please return the spreadsheet ID corresponding to filename: ' + FileName);
 return '';
}

Yukarıdaki örnekte yer alan yorumlarda belirtildiği gibi, hedef dosyaları Google Drive'daki Google E-Tablolar dosyalarına dönüştürmeniz gerekir.

İlgili Google E-Tablosu kimlikleri aşağıda kalın olarak gösterilmiştir:

  • 1. dosya: C:\Data\abc.xlsx, https://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc olur
  • 2. dosya: C:\Data\abc.xlsx, https://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ olur

Ardından, dosyaları kimliğe göre açmak için Apps Komut Dosyası işlevindeki kodu aşağıda gösterildiği gibi değiştirin:

/**
* Method to return the spreadsheet id manually.
*
* @param {string} FileName ID of the spreadsheet to be opened.
* @return {string} return the spreadsheet id.
*/
function _handle_mso_excel_get_google_spreadsheet_id(FileName) {
 // Upload the Excel files being opened by the API to Google Drive and convert
 //them to Google Sheets.
 // Determine the spreadsheet ID of the Google Sheets file created.
 // Implement this method to return the corresponding spreadsheet ID when given
 //the original file path as parameter
 if (Filename.indexOf("abc.xlsx") >= 0) {
   return "abc123Abc123Abc123abc";
 } else if (Filename.indexOf("xyz.xlsx") >= 0) {
   return "xyz456Xyz456xYz456xyZ";
 }

Kasıtlı hata

Orijinal VBA kodunuzun hata davranışını taklit etmek için dönüştürülen kodunuza kasıtlı hatalar eklenir. Bu hataları değiştirmeniz gerekmez.

Kasıtlı hata örneği

VBA'da bir dizi sınırlarının dışındaki bir öğeye erişmeye çalışırsanız kod bir istisna atar. Apps Komut Dosyası'nda, kod tanımsız değerini döndürür.

Beklenmedik sonuçları önlemek için Makro Dönüştürücü, bir dizinin sınırlarının dışındaki öğelere erişmeye çalıştığınızda istisna uygulayan Apps Komut Dosyası kodu ekler.

Bu örnek, aşağıdaki kodda gösterilmektedir:

Orijinal VBA kodu
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Dönüştürülen Apps Komut Dosyası kodu (istisna hatası eklenmeden önce)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
İstisna hatasını bildirmek için Apps Komut Dosyası kodu eklendi
/**
* Extend the regular JS array to support VB style indexing with a get method.
* @returns{*} value at the index
*/
Array.prototype.get = function() {
 var curr_res = this;
 for (var i = 0; i < arguments.length; i++) {
   if (!Array.isArray(curr_res) || curr_res.length < arguments[i]) {
     throw new Error(‘Converted VBA Error (Intentional Error): Subscript out of range’);
   }
   curr_res = curr_res[arguments[i]];
 }
 return curr_res;
};
var arr;
arr  = ["apple", "orange"];
Browser.msgBox(arr.get(5));