Corrige errores en tu código convertido

El complemento de Macro Converter automatiza la mayor parte del proceso de conversión, pero es posible que debas realizar ajustes en algunas API y en otros elementos para finalizar el código.

Usa esta guía para comprender los archivos de Apps Script (archivos GS) agregados a tu proyecto, interpretar los diferentes tipos de errores y aprender a corregirlos.

Información sobre los archivos de Apps Script que se agregan a tu proyecto

Los archivos GS adicionales se agregan a tu proyecto de Apps Script para ayudar a lograr lo siguiente:

  • Define constantes y valores de VBA que no existen en Apps Script.
  • Implementa las APIs sin convertir.
  • Resuelve las variantes.

Se agregan los siguientes archivos GS a tu proyecto de Apps Script:

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

Library.gs

En general, no es necesario modificar nada en el archivo library.gs.

El archivo library.gs define funciones y constantes que se usaron en tu código VBA y que no existen en Apps Script. Esto ayuda a que el nuevo código de Apps Script se parezca mejor al código VBA. Además, no es necesario que repitas las definiciones cada vez que se usen funciones o constantes del archivo library.gs.

Unimplemented_constructs.gs

El archivo unimplemented_constructs.gs se dirige a las construcciones o las APIs que el MacroConverter no pudo convertir. Es probable que debas modificar este archivo para que tu código funcione según lo previsto.

Ejemplo: Window.Activate()

El siguiente es un ejemplo de una API no compatible llamada Window.Activate(). Macro Converter crea una función nueva de Apps Script con un nombre similar y la define en el archivo unimplemented_constructs.gs. Como la función VBA no es compatible, la nueva función Apps Script arroja una excepción.

La función nueva se agrega al código convertido de Apps Script en todos los lugares en los que se usó la API original en el código de VBA.

Si encuentras una solución alternativa para recrear el comportamiento de la API original, solo debes actualizar la definición de la función en el archivo unimplemented_constructs.gs. Una vez que la función está definida allí, se aplica en todos los lugares donde aparece en tu proyecto de Apps Script.

Este es el ejemplo en código:

Código original de VBA

Window.activate()

Código convertido de Apps Script, agregado intercalado

_api_window_activate();

Se agregó la definición de la función al archivo unimplemented_constructs.gs

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

El archivo variant_resolutions.gs se agrega a tu proyecto de Apps Script si no se puede determinar el tipo de objeto. Esto puede ocurrir por varios motivos, por ejemplo, una API con varios tipos de datos que se muestran o el objeto se declara como una variante.

Macro Converter agrega una función nueva a este archivo llamada __handle_resolve_<api>() que reemplaza la API en cuestión y ayuda a determinar el tipo de objeto.

En algunos casos, es posible que debas actualizar la función __handle_resolve_<api>() para declarar de forma manual el tipo de objeto. Consulta Tipo de objeto no compatible.

Ejemplo: name()

Muchos tipos de objetos en VBA definen una API de name(). Por lo general, el equivalente de Apps Script es getName(), pero no para todos los tipos de objeto. Pueden ocurrir varios casos alternativos, como los siguientes:

  • La API equivalente del objeto tiene un nombre diferente de getName().
  • El objeto no tiene una API de Apps Script para obtener su nombre.
  • No hay un objeto de Apps Script equivalente.

Cuando no se determina el tipo de objeto, Macro Converter crea una función nueva llamada __handle_resolve_name en el archivo variant_resolutions.gs.

Este es el ejemplo en código:

Código original de VBA

a = Selection.name

En este caso, se llama a name() de la API en la selección actual. La selección puede ser un objeto de hoja o un objeto de forma. Si es un objeto de hoja, la traducción es getName(), pero si es un objeto Shape, no hay equivalente en Apps Script.

Código convertido de Apps Script, agregado intercalado

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

La función __handle_resolve_name() que aparece a continuación se agrega al archivo variant_resolution.gs para resolver diferentes tipos de objetos. La función verifica el tipo de objeto y, luego, usa getName() si se admite o arroja un error si no se admite getName().

Se agregó la definición de la función al archivo variant_resolution.gs

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

Cómo buscar errores

Cuando te encuentras con un error en el código convertido de Apps Script, el mensaje especifica el tipo de error y su ubicación. El formato del mensaje de error depende del entorno de ejecución de Apps Script que uses.

Si usas el tiempo de ejecución predeterminado de V8, verás un error similar al siguiente:

_api_windows_active (unimplemented_constructs:2:3)

Esto significa que el error se encuentra en el archivo unimplemented_constructs.gs, en la línea 2, carácter 3.

Si utilizas el entorno de ejecución obsoleto de Rhino, verás un error similar al siguiente:

unimplemented_constructs:2 (_api_windows_active)

Esto significa que el error se encuentra en el archivo unimplemented_constructs.gs, en la línea 2.

Tipos de errores

Puedes corregir la mayoría de los errores que se encuentran en los archivos unimplemented_constructs.gs y variant_resolution.gs descritos anteriormente.

Entre los tipos de errores que puedes encontrar, se incluyen los siguientes:

API no implementada

Una API no implementada es una API que Macro Converter no puede convertir de VBA a Apps Script, y no existe una solución alternativa conocida para la API.

Por lo general, las APIs no implementadas se agregan como funciones vacías (a veces con firmas vacías) al archivo unimplemented_constructs.gs. Si no se pudo determinar el tipo de objeto, es posible que la API no implementada se agregue al archivo variant_resolution.gs en su lugar.

En el informe de compatibilidad que generaste antes de la conversión, esta API se etiqueta como Requiere más investigación.

Si no corriges este tipo de API en tu código VBA antes de convertir el archivo, verás cómo aparecerá en el proyecto Apps Script:

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

Corrige errores de la API no implementados

Define la API no implementada con las APIs de Apps Script o las bibliotecas JS existentes. Para hacerlo, sigue estos pasos:

  1. Abre el código convertido de Apps Script en la ubicación del error. Consulta Cómo buscar errores.
  2. Arriba de la función, lee el comentario que se agregó. En algunos casos, el comentario sugiere cómo implementar la API en Apps Script.
  3. Si no puedes encontrar una manera de implementar la API en Apps Script, procura quitarla de tu código.
  4. Si no puedes encontrar una solución alternativa o quitar esta API de tu código y la macro arroja este error, no puedes convertir esta macro.

Ejemplos de errores de API no implementados

A continuación, se incluyen ejemplos de situaciones de API no implementadas y cómo corregirlas:

  • No hay una Apps Script equivalente: Muestra una solución alternativa indirecta para Chart.Protect, una API que no existe en Apps Script.
  • Un tipo de objeto desconocido: Muestra cómo controlar un tipo de objeto que es una variable y cómo implementar un tipo de objeto no compatible que se puede volver a crear en Apps Script.
Ejemplo 1: No hay una API desconocida o Apps Script equivalente

En este ejemplo, Chart.Protect no se convirtió automáticamente porque no hay forma de proteger un gráfico en Hojas de cálculo de Google.

/**
* 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.');
}
Aunque no puedes proteger un gráfico, sí puedes proteger su rango de datos para que los datos no se puedan cambiar.

A continuación, se muestra un ejemplo de implementación de la protección del rango:
/**
* 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();
}
}
Ejemplo 2: Tipo de objeto no compatible

Cuando se desconoce el tipo de objeto, el error de la API no implementado se agrega al archivo variant_resolution.gs. En el siguiente ejemplo, se amplía el ejemplo anterior de la API de VBA name(). Consulta variant_resolution.gs.

En este ejemplo, aprenderás lo siguiente:

  1. Cómo se convierte la API de name() en una función nueva en el archivo variant_resolution.gs.
  2. Cómo se llama a la función nueva en el código convertido
  3. Cómo crear una solución alternativa para CommandBar, un tipo de objeto no compatible, en Apps Script.

1. Dado que el código convertido no puede determinar el tipo de objeto exacto en el que se llama a name(), Macro Converter crea una función nueva llamada __handle_resolve_name, que se muestra a continuación.

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. Supongamos que el código VBA define una función PrintName() que llama a la API name(). A continuación, se muestra el código de la VBA:

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
Como se llama a `name()` en un objeto que es una variable, el código convertido no conoce el tipo de objeto en el momento de la conversión. El código convertido de Apps Script llamará a la función `__handle_resolve_name`:
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

3. Supongamos que tu código VBA llama a la función PrintName() en el tipo de objeto CommandBar. A continuación, se muestra el código de la VBA:

PrintName Application.CommandBars.item("Standard")
CommandBar no es compatible con Apps Script, por lo que tampoco se admiten los dos métodos que se usaron en el código de VBA anterior.
  • Application.CommandBars(): En el VBA, se muestra una lista de todos los objetos CommandBar.
  • CommandBars.item(): En el VBA, se muestra un objeto CommandBar específico.
Debido a que este tipo de objeto no es compatible con Apps Script, el código convertido crea las siguientes funciones en el archivo `unimplemented_constructs.gs` que debes definir.
  • _api_application_commandbars()
  • _api_commandbars_item()
Se llama a las funciones en el código convertido, como se muestra a continuación:
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.');
}

Para que funcionen las funciones nuevas, sigue estos pasos:

3.1 Define un nuevo tipo de objeto que cree las funciones de CommandBars y una colección nueva de CommandBars similar a la que existe en VBA.

3.2 Agrega un método getName() para el tipo de objeto nuevo.

Los pasos 3.1 y 3.2 se muestran en el siguiente código. Los objetos de menú se crean como un tipo de objeto nuevo que imita el comportamiento de CommandBars.

// 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 Modifica la función __handle_resolve_name en el archivo variant_resolution.gs para controlar el tipo de objeto nuevo. Agrega una sección a la función, como se muestra a continuación:

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 Define las dos funciones creadas en el archivo unimplemented_constructs.gs (_api_application_commandbars() y _api_commandbars_item()). Este paso garantiza que funcionen las llamadas originales de la función.

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

Construcciones de lenguaje no implementadas

Una construct es un elemento del lenguaje de código que controla el flujo de ejecución o la visualización de datos. Por ejemplo, bucles, etiquetas, eventos y gotos. Esta es una lista de todas las construcciones de VBA.

Las construcciones que Macro Converter no puede convertir se consideran construcciones de lenguaje no implementadas.

Cuando Macro Converter determina que existe una construcción de lenguaje no implementada, inserta un comentario TODO.

No se admiten las siguientes construcciones de VBA:

Cómo corregir errores de construcción de lenguaje no implementados

  1. Actualiza tu código para que tu lógica no dependa de la construcción de lenguaje no compatible.
  2. Abre el código convertido de Apps Script en la ubicación del error. Consulta Cómo buscar errores.
  3. Según la lógica del código, actualízalo de manera que no requiera la construcción del lenguaje no compatible.
  4. Si no puedes encontrar una manera de reescribir código sin la construcción de lenguaje no compatible, no podrás convertir esta macro.

Ejemplos de errores de construcción de lenguaje no implementados

Una de las construcciones de lenguaje no implementadas más comunes es una sentencia GoTo. Puedes reemplazar algunas instrucciones GoTo de VBA por bucles. A continuación, se muestran dos ejemplos de uso de bucles en lugar de declaraciones GoTo.

Ejemplo 1: Reemplaza GoTo por While Loop

Código original de VBA
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
Código equivalente de Apps Script
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);
}

Ejemplo 2: Reemplaza GoTo por el bucle For

Código original de VBA
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
Código equivalente de Apps Script
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);
}

API parcialmente compatible

Para las APIs parcialmente compatibles, algunos parámetros de entrada son compatibles con Apps Script y otros no.

Por ejemplo, la API legend_position de VBA se usa para definir la leyenda en un gráfico de Excel. Admite varios tipos de valores de entrada, incluidos los siguientes:

  • xlLegendPositionBottom: Ubica la leyenda en la parte inferior del gráfico.
  • xlLegendPositionCorner: Ubica la leyenda en la esquina del gráfico.
  • xlLegendPositionCustom: Ubica la leyenda en posiciones personalizadas del gráfico.

Apps Script tiene un código equivalente que solo admite algunos de esos valores. No se admiten los siguientes valores:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

Para marcar los valores no admitidos de las APIs parcialmente admitidas en tu código convertido, se agrega una condición de validación al archivo library.gs que verifica esos valores. Por ejemplo:

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

Si la condición de validación encuentra uno de los valores no admitidos, se crea una función de controlador de errores, _handle_<API_name>_error, en el archivo unimplemented_constructs.gs.

La función muestra un error del usuario y no reemplazará el valor con un valor admitido. Por ejemplo:

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

Cómo corregir errores de API parcialmente admitidos

Define la función _handle_<API_name>_error para reemplazar los valores no admitidos por una solución alternativa aceptable para tus necesidades.

  1. Abre el código convertido de Apps Script en la ubicación del error. Consulta Cómo buscar errores.
  2. Lee el comentario que aparece sobre la función para comprender qué valores son compatibles y cuáles no.
  3. En el caso de los valores no admitidos, determina qué valores admitidos pueden actuar como reemplazo adecuado.
  4. Actualiza la función _handle_<API_name>_error para mostrar un valor admitido en su lugar.
  5. Si no puedes encontrar una manera de reemplazar el valor no admitido, no puedes convertir esta macro.

Ejemplo de un error de API parcialmente admitido

En el siguiente ejemplo, se amplía la API de VBA legend_position mencionada anteriormente. Consulta API parcialmente compatible.

A continuación, se muestra un ejemplo de código original de VBA que usa un valor no admitido, xlLegendPositionCustom.

Charts(1).Legend.Position = xlLegendPositionCustom

Macro Converter agrega la siguiente función al archivo unimplemented_constructs.gs:

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

Trabajo manual necesario

Trabajo manual necesario significa que la API de VBA se puede convertir en Apps Script, pero necesita una solución alternativa.

En el informe de compatibilidad que generaste antes de la conversión, este tipo de API se etiqueta como Compatible con soluciones alternativas.

Si no corriges este tipo de API en tu código VBA antes de convertir el archivo, verás cómo aparecerá en el proyecto Apps Script:

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

Cómo corregir errores de tareas manuales necesarias

Implementa una solución alternativa para que la API funcione según lo previsto. 1. Abre el código convertido de Apps Script en la ubicación del error. Consulta Cómo buscar errores. 1. Lee el comentario que aparece sobre la función para comprender qué APIs se pueden usar como solución alternativa. 1. Si no encuentras una solución alternativa adecuada, considera quitar la API de tu código. 1. Si no puedes encontrar una solución alternativa o quitar esta API de tu código y la macro arroja un error, no podrás convertir esta macro.

Ejemplos de errores de trabajo manual necesario

Estos son ejemplos de APIs que arrojan errores de trabajo manual necesarios y cómo corregirlos:

Ejemplo 1: Autocorrect.Addreplacement

En el siguiente ejemplo, se puede convertir la API de VBA Autocorrect.Addreplacement, pero se necesita una solución alternativa. Macro Converter sugiere cómo implementar la función en los comentarios del código.

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

}

A continuación, se muestra la implementación de la API de Autocorrect.Addreplacement:

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

Ejemplo 2: Workbook.open()

La API de VBA workbook.open() abre un archivo local en función de una ruta de archivo.

Supongamos que workbook.open() abre dos archivos en el código VBA:

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

A continuación, se muestra cómo Macro Converter reemplaza Workbook.open() por Apps Script en todas las ubicaciones en las que se usa Workbook.open() para abrir el archivo 1:

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
El siguiente error se agrega al archivo unimplemented_constructs.gs en el proyecto de Apps Script:
/**
* 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 '';
}

Como se indica en los comentarios del ejemplo anterior, debes convertir los archivos de destino en archivos de Hojas de cálculo de Google en Google Drive.

Los ID correspondientes de las hojas de cálculo de Google aparecen en negrita a continuación:

  • Archivo n.o 1: C:\Data\abc.xlsx se convierte en https://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc
  • Archivo n.o 2: C:\Data\abc.xlsx se convierte en https://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ

Luego, modifica el código en la función Apps Script para abrir los archivos por ID, como se muestra a continuación:

/**
* Method to return the spreadsheet id manually.
*
* @param {string} FileName ID of the spreadsheet to be opened.
* @return {string} return the spreadsheet id.
*/
function _handle_mso_excel_get_google_spreadsheet_id(FileName) {
 // Upload the Excel files being opened by the API to Google Drive and convert
 //them to Google Sheets.
 // Determine the spreadsheet ID of the Google Sheets file created.
 // Implement this method to return the corresponding spreadsheet ID when given
 //the original file path as parameter
 if (Filename.indexOf("abc.xlsx") >= 0) {
   return "abc123Abc123Abc123abc";
 } else if (Filename.indexOf("xyz.xlsx") >= 0) {
   return "xyz456Xyz456xYz456xyZ";
 }

Error intencional

Los errores intencionales se agregan a tu código convertido para imitar el comportamiento de error del código de VBA original. No es necesario que modifiques estos errores.

Ejemplo de un error intencional

Si intentas acceder a un elemento más allá de los límites de un array en VBA, el código arrojará una excepción. En Apps Script, el código muestra "indefinido".

Para evitar resultados inesperados, Macro Converter agrega código de Apps Script que arroja una excepción si intentas acceder a elementos más allá de los límites de un array.

Este ejemplo se muestra en el siguiente código:

Código original de VBA
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Código convertido de Apps Script (antes de que se agregue el error de excepción)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
Se agregó código de Apps Script para arrojar un error de excepción
/**
* 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));