Fehler im konvertierten Code beheben

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

In diesem Leitfaden erfahren Sie, wie Sie die Apps Script-Dateien (GS-Dateien) interpretieren, die Ihrem Projekt hinzugefügt wurden, wie Sie die verschiedenen Fehlertypen interpretieren und wie Sie Fehler beheben.

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

Ihrem Apps Script-Projekt werden zusätzliche GS-Dateien hinzugefügt, um:

  • 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 in der Datei library.gs nichts ändern.

In der Datei library.gs werden Funktionen und Konstanten definiert, die in Ihrem VBA-Code verwendet wurden, aber in Apps Script nicht vorhanden sind. So ähnelt der neue Apps Script-Code Ihrem VBA-Code besser. 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 enthält Konstrukte oder APIs, die vom Macro Converter nicht konvertiert werden konnten. Sie müssen diese Datei wahrscheinlich ändern, damit Ihr Code wie vorgesehen funktioniert.

Beispiel: Window.Activate()

Das folgende Beispiel zeigt eine nicht unterstützte API namens Window.Activate(). Der Makrokonverter 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 dem konvertierten Apps Script-Code überall dort hinzugefügt, wo die ursprüngliche API im VBA-Code verwendet wurde.

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

Hier ist das Beispiel im Code:

Originaler VBA-Code

Window.activate()

Konvertierter Apps Script-Code, inline eingefü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. wenn eine API mehrere Rückgabetypen hat oder das Objekt selbst als Variante deklariert ist.

Der Makrokonverter fügt dieser Datei eine neue Funktion namens __handle_resolve_<api>() hinzu, die die betreffende API ersetzt und hilft, den Objekttyp zu bestimmen.

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

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

  • Die entsprechende API des Objekts hat einen anderen Namen als getName().
  • Für das Objekt ist keine Apps Script API verfügbar, um seinen Namen abzurufen.
  • Es gibt kein entsprechendes Apps Script-Objekt.

Wenn der Objekttyp nicht ermittelt wird, erstellt der Makrokonverter in der Datei variant_resolutions.gs eine neue Funktion mit dem Namen __handle_resolve_name.

Hier ist das Beispiel im Code:

Originaler VBA-Code

a = Selection.name

In diesem Fall wird die API name() für die aktuelle Auswahl aufgerufen. Die Auswahl kann ein Sheet- oder ein Shape-Objekt sein. Wenn es sich um ein Sheet-Objekt handelt, lautet die Übersetzung getName(). Wenn es sich um ein Shape-Objekt handelt, gibt es in Apps Script kein Äquivalent.

Konvertierter Apps Script-Code, inline eingefügt

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

Die Funktion __handle_resolve_name() unten wird der Datei variant_resolution.gs hinzugefügt, um verschiedene Objekttypen zu berücksichtigen. Die Funktion prüft den Objekttyp und verwendet dann getName(), falls unterstützt, oder gibt einen Fehler aus, falls 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, wird in der Meldung der Fehlertyp und die Position des Fehlers angegeben. Das Format der Fehlermeldung hängt davon ab, welche Apps Script-Laufzeit Sie verwenden.

Wenn Sie die Standard-V8-Laufzeit verwenden, 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 die eingestellte Rhino-Laufzeit verwenden, wird ein Fehler wie der folgende 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, lassen sich beheben.

Folgende Fehler können auftreten:

Nicht implementierte API

Eine nicht implementierte API ist eine API, die der Macro Converter nicht von VBA in Apps Script konvertieren kann und für die es keine bekannte Problemumgehung gibt.

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

In dem Kompatibilitätsbericht, den Sie vor der Umstellung erstellt haben, ist diese API mit Weitere Untersuchungen erforderlich gekennzeichnet.

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

/**
* 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_<API_name>(param1, param2, ....) {
  ThrowException("API  not supported yet.");
}

Fehler aufgrund nicht implementierter APIs 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 des Fehlers. Weitere Informationen finden Sie unter Fehler finden.
  2. Lesen Sie den Kommentar, der über der Funktion hinzugefügt wurde. 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 ausgibt, können Sie das Makro nicht konvertieren.

Beispiele für nicht implementierte API-Fehler

Hier sind Beispiele für nicht implementierte API-Szenarien und Informationen zur Fehlerbehebung:

  • Kein entsprechendes Apps Script:Chart.Protect ist eine API, die in Apps Script nicht vorhanden ist. Hier wird eine indirekte Problemumgehung gezeigt.
  • Unbekannter Objekttyp: Hier wird gezeigt, wie ein Objekttyp behandelt wird, der eine Variable ist, und wie ein nicht unterstützter Objekttyp implementiert wird, der in Apps Script neu erstellt werden kann.
Beispiel 1: Kein entsprechendes Apps Script oder 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.');
}
Sie können zwar kein Diagramm schützen, aber den Datenbereich des Diagramms, damit die Daten nicht geändert werden können.

Im Folgenden finden Sie ein Beispiel für die Implementierung des Schutzes 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 „Nicht implementierte API“ der Datei variant_resolution.gs hinzugefügt. Das folgende Beispiel baut auf dem VBA-Beispiel für die name()-API oben auf. Weitere Informationen finden Sie unter variant_resolution.gs.

In diesem Beispiel erfahren Sie Folgendes:

  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. So erstellen Sie in Apps Script eine Problemumgehung für CommandBar, einen nicht unterstützten Objekttyp.

1. Da im konvertierten Code der genaue Objekttyp, für den name() aufgerufen wird, nicht ermittelt werden kann, 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, im VBA-Code wird eine PrintName()-Funktion definiert, die die name()-API aufruft. Der VBA-Code ist unten zu sehen:

‘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, in Ihrem VBA-Code wird die Funktion PrintName() für den Objekttyp CommandBar aufgerufen. Der VBA-Code ist unten zu sehen:

PrintName Application.CommandBars.item("Standard")
CommandBar wird in Apps Script nicht unterstützt. Daher werden auch die beiden im VBA-Code oben verwendeten Methoden nicht unterstützt.
  • Application.CommandBars(): In VBA wird damit eine Liste aller CommandBar-Objekte zurückgegeben.
  • CommandBars.item(): In VBA wird damit ein bestimmtes CommandBar-Objekt zurückgegeben.
Da dieser Objekttyp in Apps Script nicht unterstützt wird, werden im 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 wie unten gezeigt aufgerufen:
PrintName(_api_commandbars_item(_api_application_commandbars(), "Standard")))

Heres 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.');
}

So nutzen Sie die neuen Funktionen:

3.1 Definieren Sie einen neuen Objekttyp, der die Funktionen von CommandBars und eine neue Sammlung von CommandBars erstellt, ähnlich wie 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 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 Ändern Sie die Funktion __handle_resolve_name in der Datei variant_resolution.gs, um den neuen Objekttyp zu verarbeiten. 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 erstellt wurden (_api_application_commandbars(), _api_commandbars_item()). Dadurch wird sichergestellt, 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 Konstrukt ist ein Element der Codesprache, das den Ausführungsablauf oder die Datendarstellung steuert. Dazu gehören beispielsweise Schleifen, Labels, Ereignisse und Gotos. Hier finden Sie eine Liste aller VBA-Konstrukte.

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

Wenn der Makrokonverter feststellt, dass ein nicht implementiertes Sprachkonstrukt vorhanden ist, fügt er einen TODO-Kommentar ein.

Die folgenden VBA-Konstrukte werden nicht unterstützt:

Fehler aufgrund nicht implementierter Sprachkonstrukte 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 des Fehlers. Weitere Informationen finden Sie unter Fehler finden.
  3. Aktualisieren Sie den Code basierend auf seiner Logik so, dass das nicht unterstützte Sprachkonstrukt nicht mehr erforderlich ist.
  4. Wenn Sie keine Möglichkeit finden, den Code ohne das nicht unterstützte Sprachkonstrukt neu zu schreiben, können Sie das Makro nicht konvertieren.

Beispiele für Fehler bei nicht implementierten Sprachkonstrukten

Eines der häufigsten nicht implementierten Sprachkonstrukte ist eine GoTo-Anweisung. Sie können einige VBA-GoTo-Anweisungen 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

Originaler 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 Loop“ ersetzen

Originaler 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.

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

  • xlLegendPositionBottom: Die Legende wird unten im Diagramm platziert.
  • xlLegendPositionCorner: Die Legende wird in der Ecke des Diagramms platziert.
  • xlLegendPositionCustom: Die Legende wird an 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 eine 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);
}

Fehler bei teilweise unterstützten APIs beheben

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

  1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle des Fehlers. 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 als geeigneter Ersatz infrage kommen.
  4. Aktualisieren Sie die Funktion _handle_<API_name>_error so, dass sie stattdessen einen unterstützten Wert zurückgibt.
  5. Wenn Sie keine Möglichkeit finden, den nicht unterstützten Wert zu ersetzen, können Sie das Makro nicht konvertieren.

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

Das folgende Beispiel baut auf der oben erwähnten VBA API legend_position auf. Weitere Informationen finden Sie unter Teilweise unterstützte API.

Unten sehen Sie ein Beispiel für ursprünglichen VBA-Code, in dem der nicht unterstützte Wert xlLegendPositionCustom verwendet wird.

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, aber eine Problemumgehung erforderlich ist.

Im Kompatibilitätsbericht, den Sie vor der Umstellung erstellt haben, ist dieser API-Typ mit Supported with workarounds (Mit Workarounds unterstützt) gekennzeichnet.

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

/**
* 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_<API_name>(param1, param2, ....) {
 ThrowException("API  not supported yet.");
}

Fehler beheben, die manuellen Aufwand erfordern

Implementieren Sie eine Problemumgehung für die API, damit sie wie vorgesehen funktioniert. 1. Öffnen Sie den konvertierten Apps Script-Code an der Stelle des Fehlers. Weitere Informationen finden Sie unter Fehler finden. 1. Lesen Sie den Kommentar über der Funktion, um zu erfahren, welche APIs für eine Umgehungslösung verwendet werden können. 1. Wenn Sie keine geeignete Problemumgehung finden, sollten Sie die API aus Ihrem Code entfernen. 1. Wenn Sie keine Problemumgehung finden oder diese API nicht aus Ihrem Code entfernen können und Ihr Makro einen Fehler ausgibt, können Sie dieses Makro nicht konvertieren.

Beispiele für Fehler, die manuelle Arbeit erfordern

Hier sind Beispiele für APIs, die Fehler vom Typ „Manuelle Arbeit erforderlich“ auslösen, 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 ein Workaround erforderlich. Der Makro-Konverter 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.');

}

Die Implementierung der Autocorrect.Addreplacement API wird unten gezeigt:

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 zwei Dateien von workbook.open() geöffnet:

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

Im Folgenden sehen Sie, wie der Makrokonverter Workbook.open() durch Apps Script ersetzt, wenn 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 Beispiel oben beschrieben, müssen Sie die Zieldateien in Google Drive in Google Sheets-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 anhand der ID zu öffnen, wie unten gezeigt:

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

Absichtlicher Fehler

Absichtliche Fehler werden dem konvertierten Code hinzugefügt, um das Fehlerverhalten des ursprünglichen VBA-Codes zu imitieren. Sie müssen diese Fehler nicht beheben.

Beispiel für einen absichtlichen Fehler

Wenn Sie in VBA versuchen, auf ein Element außerhalb der Grenzen eines Arrays zuzugreifen, löst der Code eine Ausnahme aus. In Apps Script gibt der Code „undefined“ 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:

Originaler VBA-Code
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Konvertierter Apps Script-Code (bevor der Ausnahme-Fehler 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 zum Auslösen des Ausnahmefehlers hinzugefügt
/**
* 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));