Fehler im konvertierten Code beheben

Das Add-on Macro Converter automatisiert den Großteil des Konvertierungsprozesses. Möglicherweise müssen Sie jedoch Anpassungen an einigen APIs und anderen Elementen vornehmen, um Ihren Code abzuschließen.

In dieser Anleitung erfahren Sie mehr über die Apps Script-Dateien (GS-Dateien), die Ihrem Projekt hinzugefügt wurden, um die verschiedenen Fehlertypen zu interpretieren und um Fehler zu beheben.

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

In Ihrem Apps Script-Projekt werden zusätzliche GS-Dateien hinzugefügt, um Folgendes zu ermöglichen:

  • VBA-Konstanten und -Werte definieren, die in Apps Script nicht vorhanden sind
  • Nicht konvertierte APIs implementieren
  • Beheben Sie Varianten.

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 an der Datei library.gs nichts ä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 besser Ihrem VBA-Code. Außerdem müssen Sie Definitionen nicht jedes Mal wiederholen, wenn Funktionen oder Konstanten aus der Datei library.gs verwendet werden.

Unimplemented_constructs.gs

Die Datei unimplemented_constructs.gs adressiert Konstrukte oder APIs, die vom Makrokonverter nicht konvertiert werden konnten. Wahrscheinlich müssen Sie diese Datei ändern, damit Ihr Code wie vorgesehen funktioniert.

Beispiel: Window.Activate()

Das folgende Beispiel zeigt eine nicht unterstützte API namens 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 Behelfslösung finden, um das Verhalten der ursprünglichen API neu zu erstellen, 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 im Apps Script-Projekt angezeigt wird.

Hier ist das Beispiel im Code:

Ursprünglicher VBA-Code

Window.activate()

Umgewandelter 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. Das kann verschiedene Gründe haben, z. B. weil eine API mehrere Rückgabetypen hat oder das Objekt selbst als Variante deklariert ist.

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

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

Beispiel: name()

Viele Objekttypen in VBA definieren eine name() API. Normalerweise ist die entsprechende Apps Script-Äquivalent getName(), aber nicht für jeden Objekttyp. Es können mehrere alternative Fälle auftreten:

  • Die entsprechende API des Objekts hat eine andere Bezeichnung als getName().
  • Das Objekt hat keine Apps Script API, um seinen Namen abzurufen.
  • 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 Beispiel im Code:

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. Handelt es sich um ein Tabellenobjekt, lautet die Übersetzung getName(). Handelt es sich jedoch um ein Formobjekt, gibt es in Apps Script kein Äquivalent.

Umgewandelter Apps Script-Code, inline hinzugefügt

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

Die folgende __handle_resolve_name()-Funktion wird der Datei variant_resolution.gs hinzugefügt, um verschiedene Objekttypen zu ermitteln. Die Funktion prüft den Objekttyp und verwendet 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 suchen

Wenn im konvertierten Apps Script-Code ein Fehler auftritt, werden in der Meldung die Fehlerart und die Fehlerquelle angegeben. Das Format der Fehlermeldung hängt von der Apps Script-Laufzeit ab, die Sie verwenden.

Wenn Sie sich in der standardmäßigen V8-Laufzeit 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.

In der verworfenen Rhino-Laufzeit wird eine Fehlermeldung wie diese angezeigt:

unimplemented_constructs:2 (_api_windows_active)

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

Fehlertypen

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

Zu den Fehlern, die auftreten können, gehören:

Nicht implementierte API

Eine nicht implementierte API ist eine API, die mit dem Makrokonverter nicht von VBA in Apps Script konvertiert werden kann. Es gibt dafür keine bekannte Problemumgehung.

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 stattdessen die nicht implementierte API möglicherweise der Datei variant_resolution.gs hinzugefügt.

Im Kompatibilitätsbericht, den Sie vor der Conversion 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 sich der Fehler befindet. Siehe Fehler finden.
  2. Lesen Sie über der Funktion den Kommentar, der hinzugefügt wurde. In einigen Fällen wird in dem 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, können Sie sie aus dem Code entfernen.
  4. Wenn Sie keine Problemumgehung finden oder die API nicht aus Ihrem Code entfernen können und Ihr Makro diesen Fehler auslöst, können Sie das Makro nicht konvertieren.

Beispiele für nicht implementierte API-Fehler

Im Folgenden finden Sie Beispiele für nicht implementierte API-Szenarien und wie Sie diese beheben können:

  • Es gibt kein entsprechendes Apps Script: Hier wird eine indirekte Problemumgehung für die API Chart.Protect gezeigt, die in Apps Script nicht vorhanden ist.
  • Unbekannter Objekttyp: Hier erfahren Sie, wie Sie mit einem Objekttyp umgehen, bei dem es sich um eine Variable handelt, und wie Sie einen nicht unterstützten Objekttyp implementieren, der in Apps Script neu erstellt werden kann.
Beispiel 1: Kein entsprechendes 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, sodass die Daten nicht geändert werden können.

Im Folgenden finden Sie eine Beispielimplementierung für den 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 nicht implementierte API-Fehler der Datei variant_resolution.gs hinzugefügt. Das folgende Beispiel basiert auf dem obigen Beispiel für die VBA name() API. Weitere Informationen finden Sie unter variant_resolution.gs.

In diesem Beispiel lernen Sie:

  1. Wie die name() API in eine neue Funktion in der Datei variant_resolution.gs konvertiert wird
  2. Wie die neue Funktion im konvertierten Code aufgerufen wird
  3. Problemumgehung für den nicht unterstützten Objekttyp CommandBar in Apps Script erstellen

1. Da der konvertierte Code nicht genau den Objekttyp bestimmen kann, auf den name() aufgerufen wird, erstellt der Makrokonverter eine neue Funktion mit dem Namen __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. So sieht der VBA-Code aus:

‘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, kann der konvertierte Code zum Zeitpunkt der Konvertierung den Objekttyp nicht kennen. 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. So sieht der VBA-Code aus:

PrintName Application.CommandBars.item("Standard")
CommandBar wird in Apps Script nicht unterstützt. Daher werden die beiden Methoden, die im VBA-Code oben verwendet werden, ebenfalls nicht unterstützt.
  • Application.CommandBars(): In der 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, erstellt der konvertierte Code in der Datei „unimplemented_constructs.gs“ die folgenden Funktionen, 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.');
}

Damit die neuen Funktionen richtig funktionieren, gehen Sie so vor:

3.1 Definiere einen neuen Objekttyp, der die Funktionen von CommandBars und eine neue Sammlung von CommandBars erstellt, ähnlich der in VBA.

3.2 Fügen Sie eine getName()-Methode für den neuen Objekttyp hinzu.

Die Schritte 3.1 und 3.2 sind im Code unten 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 Ändern Sie die Funktion __handle_resolve_name in der Datei variant_resolution.gs so, dass der neue Objekttyp verarbeitet wird. Fügen Sie der Funktion einen Abschnitt hinzu, wie unten gezeigt:

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 Definieren Sie die beiden Funktionen, die in der Datei unimplemented_constructs.gs (_api_application_commandbars(), _api_commandbars_item()) erstellt wurden. So 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 Gotos. Hier finden Sie eine Liste aller VBA-Konstrukte.

Konstrukte, die der Makrokonverter nicht konvertieren kann, werden als nicht implementierte Sprachkonstrukte betrachtet.

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:

Fehler bei nicht implementierten Sprachkonstruktionen 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 sich der Fehler befindet. Siehe Fehler finden.
  3. Aktualisieren Sie ihn 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 neu zu schreiben, können Sie dieses Makro nicht konvertieren.

Beispiele für nicht implementierte Sprachkonstruktionsfehler

Eines der häufigsten nicht implementierten Sprachkonstrukte ist eine GoTo-Anweisung. Einige GoTo-VBA-Anweisungen lassen sich durch Schleifen ersetzen. 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.

Mit der legend_position der VBA API wird beispielsweise die Legende in einer Excel-Grafik definiert. Es werden verschiedene Arten von Eingabewerten unterstützt, darunter:

  • xlLegendPositionBottom: Die Legende wird am unteren Rand des Diagramms platziert.
  • xlLegendPositionCorner: Die Legende wird in der Ecke des Diagramms platziert.
  • xlLegendPositionCustom: Die Legende wird an benutzerdefinierten Positionen im Diagramm platziert.

Der Code von Apps Script unterstützt nur einige dieser Werte. Die folgenden Werte werden nicht unterstützt:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

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

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

Wenn bei der Validierungsbedingung einer der nicht unterstützten Werte gefunden wird, 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 für Ihre Anforderungen geeignete Problemumgehung zu ersetzen.

  1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle, an der sich der Fehler befindet. Siehe Fehler finden.
  2. Lesen Sie den Kommentar über der Funktion, um zu erfahren, welche Werte unterstützt werden und welche nicht.
  3. Bestimmen Sie für die nicht unterstützten Werte, welche unterstützten Werte als Ersatz dienen können.
  4. Aktualisieren Sie die Funktion _handle_<API_name>_error, damit stattdessen ein unterstützter Wert zurückgegeben wird.
  5. Wenn Sie den nicht unterstützten Wert nicht ersetzen können, können Sie dieses Makro nicht konvertieren.

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

Im folgenden Beispiel wird die oben erwähnte legend_position der VBA API erweitert. Siehe Teilweise unterstützte API.

Unten sehen Sie ein Beispiel für den ursprünglichen VBA-Code, der den nicht unterstützten Wert xlLegendPositionCustom verwendet.

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 Maßnahmen erforderlich

Manuelle Maßnahmen erforderlich bedeutet, dass die VBA API in Apps Script konvertiert werden kann, dafür aber eine Problemumgehung erforderlich ist.

Im Kompatibilitätsbericht, den Sie vor der Konvertierung erstellt haben, ist dieser API-Typ als Mit Behelfslösungen 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 aufgrund manueller Arbeiten beheben

Implementieren Sie eine Behelfslösung, damit die API wie vorgesehen funktioniert. 1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle, an der sich der Fehler befindet. Siehe Fehler finden. 1. Lesen Sie den Kommentar über der Funktion, um zu erfahren, welche APIs als Behelfslösung verwendet werden können. 1. Wenn Sie keine geeignete Problemumgehung finden, können Sie die API aus dem Code entfernen. 1. Wenn Sie keine Problemumgehung finden oder die API nicht aus Ihrem Code entfernen können und Ihr Makro einen Fehler ausgibt, können Sie das Makro nicht konvertieren.

Beispiele für Fehler aufgrund von manueller Arbeit

Im Folgenden finden Sie Beispiele für APIs, die Fehler aufgrund von manueller Arbeit verursachen, und wie Sie diese beheben können:

Beispiel 1: Autocorrect.Addreplacement

Im folgenden Beispiel kann die VBA API Autocorrect.Addreplacement konvertiert werden, es ist jedoch eine Problemumgehung erforderlich. Der Macro Converter schlägt in den Codekommentaren vor, wie die Funktion implementiert werden kann.

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

Mit der VBA API „workbook.open()“ wird eine lokale Datei anhand eines Dateipfads geöffnet.

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

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

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

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 Beispiel oben gezeigt, müssen Sie die Zieldateien in 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 anhand der 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

Absichtliche Fehler werden dem konvertierten Code 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, auf ein Element zuzugreifen, das außerhalb der Grenzen eines Arrays in VBA liegt, 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 Makrokonverter Apps Script-Code hinzu, der eine Ausnahme auslöst, wenn Sie versuchen, auf Elemente außerhalb der Grenzen eines Arrays zuzugreifen.

Dieses Beispiel wird im folgenden Code gezeigt:

Ursprünglicher VBA-Code
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Umgewandelter Apps Script-Code (bevor der Ausnahmefehler hinzugefügt wird)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
Apps Script-Code wurde hinzugefügt, um den Ausnahmefehler auszulösen
/**
* 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));