Fehler im konvertierten Code beheben

Das Macro Converter-Add-on automatisiert den Großteil des Konvertierungsprozesses. Möglicherweise müssen Sie jedoch einige APIs und andere Elemente anpassen, um Ihren Code fertigzustellen.

In dieser Anleitung erfahren Sie, welche Apps Script-Dateien (GS-Dateien) Ihrem Projekt hinzugefügt wurden, wie Sie die verschiedenen Fehlertypen interpretieren und wie Sie Fehler beheben können.

Informationen zu Apps Script-Dateien, die Ihrem Projekt hinzugefügt wurden

Zusätzliche GS-Dateien werden Ihrem Apps Script-Projekt hinzugefügt, um Folgendes zu unterstützen:

  • Definieren Sie VBA-Konstanten und -Werte, die in Apps Script nicht vorhanden sind.
  • Nicht konvertierte APIs implementieren
  • Varianten auflösen

Die folgenden GS-Dateien werden Ihrem Apps Script-Projekt hinzugefügt:

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

Library.gs

Im Allgemeinen müssen Sie nichts an der Datei library.gs ändern.

In der Datei library.gs sind Funktionen und Konstanten definiert, die in Ihrem VBA-Code verwendet wurden und in Apps Script nicht vorhanden sind. Dadurch ähnelt der neue Apps Script-Code Ihrem VBA-Code besser. Außerdem müssen Sie die Definitionen nicht bei jeder Verwendung von Funktionen oder Konstanten aus der Datei library.gs wiederholen.

Unimplemented_constructs.gs

Die Datei unimplemented_constructs.gs enthält Konstrukte oder APIs, die nicht vom Macro Converter konvertiert werden konnten. Wahrscheinlich müssen Sie diese Datei ändern, damit der Code wie vorgesehen funktioniert.

Beispiel: Window.Activate()

Das folgende Beispiel zeigt eine nicht unterstützte API mit dem Namen Window.Activate(). Der Macro Converter erstellt eine neue Apps Script-Funktion mit einem ähnlichen Namen und definiert sie in der Datei unimplemented_constructs.gs. Da die VBA-Funktion nicht unterstützt wird, löst die neue Apps Script-Funktion eine Ausnahme aus.

Die neue Funktion wird überall dort, wo die ursprüngliche API im VBA-Code verwendet wurde, in den konvertierten Apps Script-Code eingefügt.

Wenn Sie eine Problemumgehung finden, um das Verhalten der ursprünglichen API wiederherzustellen, müssen Sie nur die Definition der Funktion in der Datei unimplemented_constructs.gs aktualisieren. Sobald die Funktion dort definiert ist, wird sie überall dort angewendet, wo sie in Ihrem Apps Script-Projekt vorkommt.

Hier ist das Code-Beispiel:

Ursprünglicher VBA-Code

Window.activate()

Konvertierter Apps Script-Code, inline hinzugefügt

_api_window_activate();

Funktionsdefinition zur Datei unimplemented_constructs.gs hinzugefügt

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

Die Datei variant_resolutions.gs wird Ihrem Apps Script-Projekt hinzugefügt, wenn der Typ eines Objekts nicht ermittelt werden kann. Dies kann verschiedene Gründe haben, z. B. wenn eine API mehrere Rückgabetypen hat oder das Objekt selbst als Variante deklariert wurde.

Der Macro Converter fügt dieser Datei eine neue Funktion namens __handle_resolve_<api>() hinzu, die die betreffende API ersetzt und beim Bestimmen des Objekttyps hilft.

In einigen Fällen müssen Sie die __handle_resolve_<api>()-Funktion aktualisieren, um den Objekttyp manuell zu deklarieren. Siehe Nicht unterstützter Objekttyp.

Beispiel: name()

Für viele Objekttypen in VBA wird eine name() API definiert. Normalerweise lautet das Apps Script-Äquivalent getName(), aber nicht für jeden Objekttyp. Es können mehrere alternative Fälle auftreten:

  • Die entsprechende API des Objekts wird anders als getName() aufgerufen.
  • Das Objekt hat keine Apps Script API, um seinen Namen zu erhalten.
  • Es gibt kein entsprechendes Apps Script-Objekt.

Wenn der Objekttyp nicht ermittelt wird, erstellt der Macro Converter eine neue Funktion namens __handle_resolve_name in der Datei variant_resolutions.gs.

Hier ist das Code-Beispiel:

Ursprünglicher VBA-Code

a = Selection.name

In diesem Fall wird die API name() für die aktuelle Auswahl aufgerufen. Die Auswahl kann ein Tabellen- oder ein Formobjekt sein. Bei einem Tabellenobjekt gibt es für die Übersetzung getName(). Handelt es sich jedoch um ein Formobjekt, gibt es in Apps Script keine Entsprechung.

Konvertierter Apps Script-Code, inline hinzugefügt

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

Die folgende Funktion __handle_resolve_name() wird der Datei variant_resolution.gs hinzugefügt, um verschiedene Objekttypen zu lösen. Die Funktion prüft den Objekttyp und verwendet dann getName(), wenn er unterstützt wird, oder gibt einen Fehler aus, wenn getName() nicht unterstützt wird.

Funktionsdefinition zur Datei variant_resolution.gs hinzugefügt

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

Fehler finden

Wenn im konvertierten Apps Script-Code ein Fehler auftritt, gibt die Meldung den Fehlertyp und seinen Ort an. Das Format der Fehlermeldung hängt von der Apps Script-Laufzeit ab, die Sie verwenden.

Wenn Sie sich in der V8-Standardlaufzeit befinden, wird ein Fehler wie der folgende angezeigt:

_api_windows_active (unimplemented_constructs:2:3)

Das bedeutet, dass sich der Fehler in der Datei unimplemented_constructs.gs in Zeile 2, Zeichen 3 befindet.

Wenn Sie sich in der verworfenen Rhino-Laufzeit befinden, wird ein Fehler wie der folgende angezeigt:

unimplemented_constructs:2 (_api_windows_active)

Dies bedeutet, dass sich der Fehler in der Datei unimplemented_constructs.gs in Zeile 2 befindet.

Fehlertypen

Sie können die meisten Fehler beheben, die in den oben beschriebenen Dateien unimplemented_constructs.gs und variant_resolution.gs auftreten.

Die folgenden Fehlertypen können auftreten:

Nicht implementierte API

Eine nicht implementierte API ist eine API, die vom Macro Converter nicht von VBA in Apps Script konvertiert werden kann. Für die API gibt es keine bekannte Behelfslösung.

Nicht implementierte APIs werden der Datei unimplemented_constructs.gs normalerweise als leere Funktionen – manchmal mit leeren Signaturen – hinzugefügt. Wenn der Objekttyp nicht ermittelt werden konnte, wird möglicherweise stattdessen die nicht implementierte API der Datei variant_resolution.gs hinzugefügt.

Im Kompatibilitätsbericht, den Sie vor der Konvertierung erstellt haben, ist diese API mit Weitere Prüfung erforderlich gekennzeichnet.

Wenn Sie diesen API-Typ nicht in Ihrem VBA-Code korrigieren, bevor Sie die Datei konvertieren, sieht er im Apps Script-Projekt so aus:

/**
* 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.");
}

Nicht implementierte API-Fehler beheben

Definieren Sie die nicht implementierte API mit vorhandenen Apps Script APIs oder JS-Bibliotheken. Gehen Sie dazu folgendermaßen vor:

  1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle, an der der Fehler auftritt. Weitere Informationen finden Sie unter Fehler finden.
  2. Lesen Sie den hinzugefügten Kommentar über der Funktion. In einigen Fällen wird im Kommentar vorgeschlagen, wie die API in Apps Script implementiert werden kann.
  3. Wenn Sie keine Möglichkeit finden, die API in Apps Script zu implementieren, sollten Sie sie aus Ihrem Code entfernen.
  4. Wenn Sie keine Problemumgehung finden oder diese API nicht aus Ihrem Code entfernen können und Ihr Makro diesen Fehler auslöst, können Sie dieses Makro nicht konvertieren.

Beispiele für nicht implementierte API-Fehler

Hier sind Beispiele für nicht implementierte API-Szenarien und wie sie behoben werden:

  • Es gibt kein entsprechendes Apps Script: Hier wird eine indirekte Problemumgehung für die API Chart.Protect angezeigt, die in Apps Script nicht vorhanden ist.
  • Unbekannter Objekttyp: Hier erfahren Sie, wie Sie mit einem Variablentyp umgehen und einen nicht unterstützten Objekttyp implementieren, der in Apps Script neu erstellt werden kann.
Beispiel 1: Kein äquivalentes Apps Script oder keine unbekannte API

In diesem Beispiel wurde Chart.Protect nicht automatisch konvertiert, da es keine Möglichkeit gibt, ein Diagramm in Google Tabellen zu schützen.

/**
* 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.');
}
Auch wenn Sie ein Diagramm nicht schützen können, können Sie den Datenbereich des Diagramms schützen, damit die Daten nicht geändert werden können.

Im Folgenden finden Sie eine Beispielimplementierung zum Schutz des Bereichs:
/**
* 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();
}
}
Beispiel 2: Nicht unterstützter Objekttyp

Wenn der Objekttyp unbekannt ist, wird der Fehler der nicht implementierten API der Datei variant_resolution.gs hinzugefügt. Das folgende Beispiel erweitert das obige Beispiel der VBA name() API. Weitere Informationen finden Sie unter variant_resolution.gs.

In diesem Beispiel lernen Sie Folgendes:

  1. Konvertierung der name() API in eine neue Funktion in der Datei variant_resolution.gs
  2. Aufruf der neuen Funktion im konvertierten Code
  3. Anleitung zum Erstellen einer Problemumgehung für den nicht unterstützten Objekttyp CommandBar in Apps Script

1. Da der konvertierte Code nicht genau den Objekttyp bestimmen kann, bei dem name() aufgerufen wird, erstellt der Makrokonverter eine neue Funktion namens __handle_resolve_name (siehe unten).

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. Angenommen, der VBA-Code definiert eine PrintName()-Funktion, die die name() API aufruft. Hier der VBA-Code:

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
Da `name()` für ein Objekt aufgerufen wird, das eine Variable ist, kennt der konvertierte Code den Objekttyp zum Zeitpunkt der Konvertierung nicht. Der konvertierte Apps Script-Code ruft die Funktion „__handle_resolve_name“ auf:
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

3. Angenommen, Ihr VBA-Code ruft die Funktion PrintName() des Objekttyps CommandBar auf. Hier der VBA-Code:

PrintName Application.CommandBars.item("Standard")
CommandBar wird in Apps Script nicht unterstützt. Daher werden die beiden im obigen VBA-Code verwendeten Methoden ebenfalls nicht unterstützt.
  • Application.CommandBars(): In VBA wird eine Liste aller CommandBar-Objekte zurückgegeben.
  • CommandBars.item(): In VBA wird ein bestimmtes CommandBar-Objekt zurückgegeben.
Da dieser Objekttyp in Apps Script nicht unterstützt wird, werden durch den konvertierten Code die folgenden Funktionen in der Datei „unimplemented_constructs.gs“ erstellt, die Sie definieren müssen.
  • _api_application_commandbars()
  • _api_commandbars_item()
Die Funktionen werden im konvertierten Code so aufgerufen:
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.');
}

Führen Sie die folgenden Schritte aus, damit die neuen Funktionen funktionieren:

3.1 Einen neuen Objekttyp definieren, der die Funktionen von CommandBars und eine neue Sammlung von CommandBars erstellt, ähnlich wie in VBA.

3.2 Methode getName() für den neuen Objekttyp hinzufügen.

Die Schritte 3.1 und 3.2 sind im folgenden Code dargestellt. Menüobjekte werden als neuer Objekttyp erstellt, der das Verhalten von CommandBars nachahmt.

// 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 Funktion __handle_resolve_name in der Datei variant_resolution.gs ändern, um den neuen Objekttyp zu verarbeiten. Fügen Sie der Funktion wie unten gezeigt einen Abschnitt hinzu:

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 Die beiden in der Datei unimplemented_constructs.gs erstellten Funktionen definieren (_api_application_commandbars(), _api_commandbars_item()). Mit diesem Schritt sorgen Sie dafür, dass die ursprünglichen Aufrufe der Funktion funktionieren.

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

Nicht implementierte Sprachkonstrukte

Ein construct ist ein Element der Codesprache, das den Ausführungsablauf oder die Datenanzeige steuert. Zum Beispiel Schleifen, Labels, Ereignisse und Goos. Hier findest du eine Liste aller VBA-Konstrukte.

Konstrukte, die der Macro Converter nicht konvertieren kann, gelten als nicht implementierte Sprachkonstrukte.

Wenn der Macro Converter feststellt, dass ein nicht implementiertes Sprachkonstrukt vorhanden ist, wird ein TODO-Kommentar eingefügt.

Die folgenden VBA-Konstrukte werden nicht unterstützt:

Nicht implementierte Sprachkonstruktionsfehler beheben

  1. Aktualisieren Sie Ihren Code so, dass Ihre Logik nicht auf dem nicht unterstützten Sprachkonstrukt basiert.
  2. Öffnen Sie den konvertierten Apps Script-Code an der Stelle, an der der Fehler auftritt. Weitere Informationen finden Sie unter Fehler finden.
  3. Aktualisieren Sie den Code basierend auf der Logik des Codes so, dass das nicht unterstützte Sprachkonstrukt nicht erforderlich ist.
  4. Wenn Sie keine Möglichkeit finden, Ihren Code ohne das nicht unterstützte Sprachkonstrukt umzuschreiben, können Sie dieses Makro nicht konvertieren.

Beispiele für nicht implementierte Fehler bei der Sprachkonstruktion

Eines der häufigsten nicht implementierten Sprachkonstrukte ist eine GoTo-Anweisung. Einige VBA-GoTo-Anweisungen können durch Schleifen ersetzt werden. Im Folgenden finden Sie zwei Beispiele für die Verwendung von Schleifen anstelle von GoTo-Anweisungen.

Beispiel 1: GoTo durch While Loop ersetzen

Ursprünglicher VBA-Code
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
Entsprechender Apps Script-Code
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);
}

Beispiel 2: GoTo durch For-Schleife ersetzen

Ursprünglicher VBA-Code
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
Entsprechender Apps Script-Code
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);
}

Teilweise unterstützte API

Bei teilweise unterstützten APIs werden einige Eingabeparameter in Apps Script unterstützt, andere nicht.

Beispielsweise wird die VBA API legend_position verwendet, um die Legende in einem Excel-Diagramm zu definieren. Es werden mehrere Arten von Eingabewerten unterstützt, darunter:

  • xlLegendPositionBottom: Die Legende wird unten im Diagramm eingeblendet.
  • xlLegendPositionCorner: Fügt die Legende in der Ecke des Diagramms ein
  • xlLegendPositionCustom: Die Legende wird an den benutzerdefinierten Positionen im Diagramm platziert.

Apps Script hat einen entsprechenden Code, der nur einige dieser Werte unterstützt. Die folgenden Werte werden nicht unterstützt:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

Um nicht unterstützte Werte von teilweise unterstützten APIs in Ihrem konvertierten Code zu kennzeichnen, wird der Datei library.gs eine Validierungsbedingung hinzugefügt, die diese Werte prüft. Beispiel:

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

Wenn die Validierungsbedingung einen der nicht unterstützten Werte findet, wird in der Datei unimplemented_constructs.gs die Fehler-Handler-Funktion _handle_<API_name>_error erstellt.

Die Funktion gibt einen Nutzerfehler aus und ersetzt den Wert nicht durch einen unterstützten Wert. Beispiel:

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

Teilweise unterstützte API-Fehler beheben

Definieren Sie die Funktion _handle_<API_name>_error, um die nicht unterstützten Werte durch eine akzeptable Behelfslösung für Ihre Anforderungen zu ersetzen.

  1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle, an der der Fehler auftritt. Weitere Informationen finden Sie unter Fehler finden.
  2. Lesen Sie den Kommentar über der Funktion, um zu erfahren, welche Werte unterstützt werden und welche nicht.
  3. Ermitteln Sie für die nicht unterstützten Werte, welche unterstützten Werte ein geeigneter Ersatz sein können.
  4. Aktualisieren Sie die Funktion _handle_<API_name>_error, damit stattdessen ein unterstützter Wert zurückgegeben wird.
  5. Wenn es keine Möglichkeit gibt, den nicht unterstützten Wert zu ersetzen, kann dieses Makro nicht konvertiert werden.

Beispiel für einen teilweise unterstützten API-Fehler

Das folgende Beispiel erweitert die oben erwähnte VBA API legend_position. Siehe Teilweise unterstützte API.

Unten sehen Sie ein Beispiel für einen ursprünglichen VBA-Code mit dem nicht unterstützten Wert xlLegendPositionCustom.

Charts(1).Legend.Position = xlLegendPositionCustom

Der Macro Converter fügt der Datei unimplemented_constructs.gs die folgende Funktion hinzu:

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

Manuelle Arbeit erforderlich

Manuelle Arbeit erforderlich bedeutet, dass die VBA API in Apps Script konvertiert werden kann, jedoch eine Problemumgehung erforderlich ist.

Im Kompatibilitätsbericht, den Sie vor der Konvertierung erstellt haben, ist dieser API-Typ Mit Problemumgehungen unterstützt gekennzeichnet.

Wenn Sie diesen API-Typ nicht in Ihrem VBA-Code korrigieren, bevor Sie die Datei konvertieren, sieht er im Apps Script-Projekt so aus:

/**
* 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.");
}

Fehler bei manueller Arbeit beheben

Implementieren Sie eine Problemumgehung für die API, damit sie wie vorgesehen funktioniert. 1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle, an der der Fehler auftritt. Weitere Informationen finden Sie unter Fehler finden. 1. Im Kommentar über der Funktion erfahren Sie, welche APIs zur Umgehung verwendet werden können. 1. Wenn Sie keine geeignete Problemumgehung finden, können Sie die API aus Ihrem Code entfernen. 1. Wenn Sie keine Problemumgehung finden oder diese API nicht aus Ihrem Code entfernen können und das Makro einen Fehler auslöst, können Sie dieses Makro nicht konvertieren.

Beispiele für Fehler, die bei manueller Arbeit erforderlich sind

Im Folgenden finden Sie Beispiele für APIs, die Fehler, die aufgrund manueller Arbeit erforderlich sind, und deren Behebung beheben:

Beispiel 1: Autocorrect.Addreplacement

Im folgenden Beispiel kann die VBA API Autocorrect.Addreplacement konvertiert werden. Für sie ist jedoch eine Behelfslösung erforderlich. Der Macro Converter schlägt in den Codekommentaren vor, wie die Funktion implementiert wird.

/**
* 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.');

}

Hier sehen Sie die Implementierung der Autocorrect.Addreplacement API:

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

Beispiel 2: Workbook.open()

Die VBA API workbook.open() öffnet eine lokale Datei anhand eines Dateipfads.

Angenommen, von workbook.open() im VBA-Code werden zwei Dateien geöffnet:

  • Datei 1: C:\Data\abc.xlsx
  • Datei 2: C:\Data\xyz.xlsx

Im Folgenden sehen Sie, wie der Macro Converter Workbook.open() überall dort durch Apps Script ersetzt, wo Workbook.open() zum Öffnen von Datei 1 verwendet wird:

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
Der folgende Fehler wird der Datei unimplemented_constructs.gs im Apps Script-Projekt hinzugefügt:
/**
* 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 '';
}

Wie in den Kommentaren im obigen Beispiel angegeben, müssen Sie die Zieldateien auf Google Drive in Google Tabellen-Dateien konvertieren.

Die entsprechenden Google-Tabellen-IDs sind unten fett formatiert:

  • Datei 1: C:\Data\abc.xlsx wird zu https://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc
  • Datei 2: C:\Data\abc.xlsx wird zu https://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ

Ändern Sie dann den Code in der Apps Script-Funktion, um die Dateien wie unten gezeigt nach ID zu öffnen:

/**
* 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";
 }

Vorsätzlicher Fehler

Dem konvertierten Code werden absichtliche Fehler hinzugefügt, um das Fehlerverhalten des ursprünglichen VBA-Codes nachzuahmen. Sie müssen diese Fehler nicht ändern.

Beispiel für einen absichtlichen Fehler

Wenn Sie versuchen, außerhalb der Grenzen eines Arrays in VBA auf ein Element zuzugreifen, löst der Code eine Ausnahme aus. In Apps Script gibt der Code „nicht definiert“ zurück.

Um unerwartete Ergebnisse zu vermeiden, fügt der Macro Converter Apps Script-Code hinzu, der eine Ausnahme auslöst, wenn Sie versuchen, über die Grenzen eines Arrays hinaus auf Elemente zuzugreifen.

Dieses Beispiel sehen Sie im folgenden Code:

Ursprünglicher VBA-Code
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Konvertierter Apps Script-Code (vor Hinzufügen eines Ausnahmefehlers)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
Apps Script-Code hinzugefügt, um den Ausnahmefehler auszugeben
/**
* 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));