Fehler im konvertierten Code beheben

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

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

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

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
  • Varianten auflösen

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

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

Library.gs

In der Regel müssen Sie in der Datei library.gs nichts ändern.

In der library.gs-Datei werden Funktionen und Konstanten definiert, die in Ihrem VBA-Code verwendet wurden und in Apps Script nicht vorhanden sind. So ä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 unimplemented_constructs.gs-Datei 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()

Im Folgenden finden Sie ein Beispiel für 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 wiederherzustellen, müssen Sie lediglich die Definition der Funktion in der Datei unimplemented_constructs.gs aktualisieren. Sobald die Funktion dort definiert ist, gilt sie überall dort, wo sie in Ihrem Apps Script-Projekt verwendet wird.

Hier ist das Beispiel im Code:

Ursprünglicher VBA-Code

Window.activate()

Konvertierter Apps Script-Code, der inline eingefügt wurde

_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 Ursachen 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 bei der Bestimmung des Objekttyps hilft.

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

Beispiel: name()

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

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

Wenn der Objekttyp nicht ermittelt werden kann, erstellt der Makrokonverter in der Datei variant_resolutions.gs eine neue Funktion namens __handle_resolve_name.

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. Bei einem Tabellenobjekt ist das getName(). Bei einem Formobjekt gibt es in Apps Script kein Äquivalent.

Konvertierter Apps Script-Code, der inline eingefügt wurde

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

Die folgende __handle_resolve_name()-Funktion 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 dieser unterstützt wird, oder löst einen Fehler aus, wenn getName() nicht unterstützt wird.

Funktionsdefinition, die der Datei variant_resolution.gs hinzugefügt wurde

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 seine Position 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 sich in der verworfenen Rhino-Laufzeit befinden, wird ein Fehler wie der folgende angezeigt:

unimplemented_constructs:2 (_api_windows_active)

Der Fehler befindet sich also in Zeile 2 der Datei unimplemented_constructs.gs.

Fehlertypen

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

Folgende Fehler 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 die nicht implementierte API möglicherweise stattdessen 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_<API_name>(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 des Fehlers. Weitere Informationen finden Sie unter Fehler finden.
  2. Lesen Sie über der Funktion den hinzugefügten Kommentar. In einigen Fällen wird im Kommentar vorgeschlagen, wie die API in Apps Script implementiert werden kann.
  3. Wenn Sie die API in Apps Script nicht implementieren können, 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, lässt sich das 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 keine entsprechende Apps Script-Funktion: Hier wird eine indirekte Umgehung für Chart.Protect angezeigt, eine API, die in Apps Script nicht vorhanden ist.
  • Ein unbekannter Objekttyp: Hier erfahren Sie, wie Sie mit einem Objekttyp umgehen, der eine Variable ist, und wie Sie einen nicht unterstützten Objekttyp implementieren, 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 in Google Tabellen keine Möglichkeit gibt, ein Diagramm 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 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 „Nicht implementierte API“ der Datei variant_resolution.gs hinzugefügt. Im folgenden Beispiel wird das VBA-name()-API-Beispiel oben erweitert. Weitere Informationen finden Sie unter variant_resolution.gs.

In diesem Beispiel lernen Sie Folgendes:

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

1. Da der umgewandelte Code den genauen Objekttyp, für den name() aufgerufen wird, nicht ermitteln 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, der VBA-Code definiert eine PrintName()-Funktion, 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()“ auf ein Objekt angewendet wird, das eine Variable ist, ist der Objekttyp zum Zeitpunkt der Umwandlung im konvertierten Code nicht bekannt. 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() für den Objekttyp 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 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.');
}

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

3.1 Definieren Sie einen neuen Objekttyp, der die Funktionen von CommandBars und eine neue Sammlung von CommandBars erstellt, die der in VBA vorhandenen ähnelt.

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 Ä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 Programmiersprache, das den Ablauf der Ausführung oder die Datenanzeige steuert. Dazu gehören beispielsweise Schleifen, Labels, Ereignisse und GOTOs. Hier findest du 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, wird ein TODO-Kommentar eingefügt.

Die folgenden VBA-Konstrukte werden nicht unterstützt:

Fehler bei nicht implementierten Sprachkonstrukten 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 aufgetreten ist. Weitere Informationen finden Sie unter Fehler finden.
  3. Aktualisieren Sie den Code entsprechend der Logik so, dass das nicht unterstützte Sprachkonstrukt nicht mehr erforderlich ist.
  4. Wenn Sie keinen Weg finden, Ihren Code ohne das nicht unterstützte Sprachkonstrukt umzuschreiben, können Sie dieses 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

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 VBA API legend_position wird beispielsweise die Legende in einer Excel-Grafik definiert. Es werden mehrere Arten von Eingabewerten unterstützt, darunter:

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

In Apps Script gibt es einen entsprechenden Code, der nur einige dieser Werte unterstützt. Folgende Werte werden nicht unterstützt:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

Wenn Sie nicht unterstützte Werte teilweise unterstützter APIs in Ihrem konvertierten Code kennzeichnen möchten, wird der Datei library.gs eine Validierungsbedingung hinzugefügt, die nach diesen Werten sucht. 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 löst 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 geeignete Problemumgehung 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. Im Kommentar über der Funktion erfahren Sie, 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 dienen können.
  4. Aktualisieren Sie die Funktion _handle_<API_name>_error, damit sie stattdessen einen unterstützten Wert zurückgibt.
  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

Das folgende Beispiel erweitert die oben erwähnte VBA API legend_position. Weitere Informationen finden Sie unter Teilweise unterstützte API.

Unten sehen Sie ein Beispiel für den 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 Umgehung erforderlich ist.

Im vor der Umstellung erstellten Kompatibilitätsbericht ist diese API-Art als Unterstützt mit Umgehung gekennzeichnet.

Wenn Sie diese Art von API nicht in Ihrem VBA-Code korrigieren, bevor Sie die Datei konvertieren, wird sie 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 manuelle Arbeit 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. Im Kommentar über der Funktion erfahren Sie, welche APIs zur Umgehung verwendet werden können. 1. Wenn Sie keine geeignete Lösung finden, können Sie die API aus Ihrem Code entfernen. 1. Wenn Sie keine Lösung finden oder diese API nicht aus Ihrem Code entfernen können und Ihr Makro einen Fehler auslöst, können Sie es 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 eine Umgehung erforderlich. In den Codekommentaren des Makro-Konverters wird vorgeschlagen, 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 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, 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 Beispiel wird gezeigt, wie der Makrokonverter Workbook.open() durch AppsScript ersetzt, überall dort, 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 Beispiel oben beschrieben, müssen Sie die Zieldateien in Google Drive in Google Tabellendateien 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 so, dass die Dateien anhand der ID geöffnet werden, 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";
 }

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 vorsätzlichen 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 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 des Ausnahmefehlers)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
Apps Script-Code, der zum Auslösen des Ausnahmefehlers hinzugefügt wurde
/**
* 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));