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ı otomatik hale getirir ancak kodunuzu tamamlamak 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ılavuzdan yararlanabilirsiniz.

Projenize eklenen Apps Komut Dosyası dosyalarını anlama

Yardımcı olması 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ştirmeniz gerekmez.

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 çok 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 istenen şekilde çalışması için bu dosyayı değiştirmeniz gerekebilir.

Örnek: Window.Activate()

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

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

Orijinal API'nin davranışını yeniden oluşturmak için 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 yere uygulanır.

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

Orijinal VBA kodu

Window.activate()

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

_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 varyant olarak tanımlanması 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 tanımlamak için __handle_resolve_<api>() işlevini güncellemeniz gerekebilir. Desteklenmeyen nesne türü konusuna bakın.

Örnek: name()

VBA'daki birçok nesne türü bir name() API'sini tanımlar. Genellikle Apps Komut Dosyası'ndaki eş değer getName() olsa da her nesne türü için aynı şey değildir. Birden fazla alternatif durum ortaya çıkabilir:

  • Nesnenin eşdeğer API'si, getName() dışında bir şey olarak adlandırılır.
  • Nesnenin adını alabilecek 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, mevcut seçimde name() API'si çağrılır. Seçim bir E-Tablo nesnesi veya bir Şekil nesnesi olabilir. E-Tablo nesnesiyse çeviri getName() olur. Ancak bu bir Şekil nesnesiyse Apps Komut Dosyası'nda eşdeğeri yoktur.

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

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

Farklı nesne türlerinin çözümü için aşağıdaki __handle_resolve_name() işlevi variant_resolution.gs dosyasına eklenmiştir. İşlev, nesne türünü kontrol eder, ardından destekleniyorsa getName() öğesini kullanır veya getName() desteklenmiyorsa hata bildirir.

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ı bulma

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, kullandığınız Apps Komut Dosyası çalışma zamanına bağlıdır.

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

_api_windows_active (unimplemented_constructs:2:3)

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

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

unimplemented_constructs:2 (_api_windows_active)

Bu, hatanın unimplemented_constructs.gs dosyasında 2. satırda 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

Uygulanmamış API, Makro Dönüştürücü'nün VBA'dan Apps Komut Dosyası'na dönüştüremediği bir API'dir ve API için bilinen bir geçici çözüm yoktur.

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

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

Dosyanızı dönüştürmeden önce VBA kodunuzda bu tür API'leri düzeltmezseniz Apps Komut Dosyası projesinde şu şekilde 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.");
}

Uygulanmamış API hatalarını düzeltme

Henüz uygulanmayan 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 konumda dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümüne bakın.
  2. İşlevin üzerinde, eklenen yorumu okuyun. Bazı durumlarda yorumda, Apps Komut Dosyası'nda API'nin nasıl uygulanacağı belirtilmektedir.
  3. Apps Komut Dosyası'nda API'yi uygulamanın bir yolunu bulamıyorsanız API'yi kodunuzdan kaldırmayı düşünebilirsiniz.
  4. Geçici bir çözüm bulamaz veya bu API'yi kodunuzdan kaldıramazsanız ve makronuz bu hatayı verirse bu makroyu dönüştüremezsiniz.

Uygulanmamış API hatası örnekleri

Aşağıda, uygulanmayan API senaryolarına ve bunların nasıl düzeltileceğine dair örnekler verilmiştir:

  • 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 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 da verilerin değiştirilmemesi için grafiğin veri aralığını koruyabilirsiniz.

Aşağıda, aralığı korumanın örnek bir uygulamasını görebilirsiniz:
/**
* 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ğine daha kapsamlı olarak değinilmiştir. İlgili konu: variant_resolution.gs.

Bu örnekte öğrenecekleriniz:

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

1. Dönüştürülen kod, name() öğesinin tam olarak çağrıldığı nesne türünü belirleyemediğinden Makro Dönüştürücü, aşağıda gösterildiği gibi __handle_resolve_name adlı 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'sini çağıran bir PrintName() işlevi tanımladığını varsayalım. VBA kodu aşağıda gösterilmektedir:

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
Değişken olan bir nesnede "name()" ç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österilmektedir:

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 işlem, tüm CommandBar nesnelerinin bir listesini döndürür.
  • CommandBars.item(): Bu, VBA'da belirli bir CommandBar nesnesini döndürür.
Bu nesne türü Apps Komut Dosyası'nda desteklenmediği için dönüştürülen kod, "unImplemented_constructs.gs" dosyasında tanımlamanız gereken aşağıdaki işlevleri oluşturur.
  • _api_application_commandbars()
  • _api_commandbars_item()
İşlevler, aşağıda gösterildiği gibi dönüştürülmüş kodda ç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şlevlerinin işlevlerini oluşturan yeni bir nesne türü ve VBA'dakilere 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ğıda gösterildiği 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 (_api_application_commandbars(), _api_commandbars_item()) oluşturulan iki işlevi tanımlayın. Bu adım, işlevin orijinal çağrılarını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ünümünü kontrol eden kod dili öğesidir. Örneğin, döngüler, etiketler, etkinlikler ve goto'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, uygulanmamış 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:

Uygulanmamış dil yapısı hatalarını düzeltme

  1. Kodunuzu, mantığınızın desteklenmeyen dil yapısına dayanmaması için güncelleyin.
  2. Hatanın bulunduğu konumda dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümüne bakın.
  3. Kodun mantığına göre, 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ı hatası örnekleri

En yaygın uygulanmamış dil yapılarından biri GoTo ifadesidir. Bazı VBA GoTo ifadelerini döngülerle değiştirebilirsiniz. Aşağıda, GoTo ifadeleri yerine döngülerin kullanılmasına ilişkin iki örnek verilmiştir.

1. örnek: GoTo yerine While Loop koyun

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

Örnek 2: GoTo'yu For Loop ile 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'lerde, bazı giriş parametreleri Apps Komut Dosyası'nda desteklenirken bazıları desteklenmez.

Örneğin, Excel grafiğinde göstergeyi tanımlamak için legend_position VBA API kullanılır. Aşağıdakiler 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 grafikteki özel konumlara yerleştirir.

Apps Komut Dosyası, bu değerlerin yalnızca bir kısmını destekleyen eşdeğer bir koda sahiptir. 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ı verir 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 için _handle_<API_name>_error işlevini tanımlayın.

  1. Hatanın bulunduğu konumda dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümüne bakın.
  2. Hangi değerlerin desteklendiğini, hangilerinin desteklenmediğini anlamak için işlevin üzerindeki yorumu okuyun.
  3. Desteklenmeyen değerler için hangi desteklenen değerlerin uygun bir değişim olarak kullanılabildiğini belirleyin.
  4. Bunun yerine desteklenen bir değer döndürmek için _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'si hakkında ayrıntılı bilgi verir. Kısmen desteklenen API bölümünü inceleyin.

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

Charts(1).Legend.Position = xlLegendPositionCustom

Makro Dönüştürücü, aşağıdaki işlevi unimplemented_constructs.gs dosyasına 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 gerekli, VBA API'nin Apps Komut Dosyası'na dönüştürülebileceği ancak geçici bir çözüm gerektirdiği anlamına gelir.

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

Dosyanızı dönüştürmeden önce VBA kodunuzda bu tür API'leri düzeltmezseniz Apps Komut Dosyası projesinde şu şekilde 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 çalışma gerekli hatalarını düzeltme

API'nin beklendiği gibi çalışmasını sağlamak için API'ye yönelik bir geçici çözüm uygulayın. 1. Hatanın bulunduğu konumda dönüştürülmüş Apps Komut Dosyası kodunu açın. Hataları bulma bölümüne bakın. 1. Geçici çözümde 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 bulamaz veya bu API'yi kodunuzdan kaldıramazsanız ve makronuz hata veriyorsa bu makroyu dönüştüremezsiniz.

Manuel çalışma gerektiren hata örnekleri

Manuel çalışma gerekli hataları bildiren API'lerin örneklerini ve bunların nasıl düzeltileceğini burada bulabilirsiniz:

1. örnek: Autocorrect.Addreplacement

Aşağıdaki örnekte Autocorrect.Addreplacement VBA API dönüştürülebilir ancak bunun için geçici bir çözüm gerekir. Makro Dönüştürücü, işlevin kod yorumlarında 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 uygulanma şekli 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 workbook.open(), dosya yoluna göre yerel bir dosya 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, 1. Dosya'yı açmak için Workbook.open() hizmetinin kullanıldığı her yerde Makro Dönüştürücü'nün Workbook.open() dosyasını Apps Komut Dosyası ile nasıl değiştirdiği gösterilmektedir:

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
Aşağıdaki hata, Apps Komut Dosyası projesindeki unimplemented_constructs.gs dosyasına 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 verilen yorumlarda belirtildiği gibi, hedef dosyaları Google Drive'da Google E-Tablolar dosyalarına dönüştürmeniz gerekir.

İlgili Google E-Tablo kimlikleri aşağıda kalın harflerle yazılmıştır:

  • 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, aşağıda gösterildiği gibi, Apps Komut Dosyası işlevindeki kodu değiştirerek dosyaları kimliğe göre açın:

/**
* 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

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

Kasıtlı hata örneği

VBA'da bir dizinin 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.

Beklenmeyen 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 bir istisna oluşturan 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ülmüş 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ı 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));