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 APIs y otros elementos para finalizar tu 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.

Comprende los archivos de Apps Script que se agregaron a tu proyecto

Se agregan archivos GS adicionales a tu proyecto de Apps Script para obtener lo siguiente:

  • Define las constantes y los valores de VBA que no existen en Apps Script.
  • Implementar APIs sin convertir
  • Resolver variantes

Se agregaron 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 las funciones y constantes que se usaron en tu código de VBA y que no existen en Apps Script. Esto ayuda a que el nuevo código de Apps Script se asemeja mejor a tu código de 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 aborda las construcciones o las APIs que el convertidor de macros 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 nueva función de Apps Script con un nombre similar y la define en el archivo unimplemented_constructs.gs. Dado que la función de VBA no es compatible, la nueva función de Apps Script arroja una excepción.

La función nueva se agrega al código convertido de Apps Script en cualquier lugar donde se haya usado la API original en el código de VBA.

Si encuentras una solución alternativa para recrear el comportamiento de la API original, solo tienes que actualizar la definición de la función en el archivo unimplemented_constructs.gs. Una vez que la función se define allí, se aplica a todos los lugares en los que aparezca la función en tu proyecto de Apps Script.

Este es el ejemplo en código:

Código de VBA original

Window.activate()

Código de Apps Script convertido y agregado en línea

_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 suceder por varios motivos, por ejemplo, que una API tenga varios tipos de datos que se muestran o que el objeto se declare como una variante.

Macro Converter agrega una nueva función 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 cada tipo de objeto. Pueden ocurrir varios casos alternativos:

  • La API equivalente del objeto se llama algo 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 de VBA original

a = Selection.name

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

Código de Apps Script convertido y agregado en línea

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 es compatible o muestra 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 estás en el entorno de ejecución predeterminado V8, verás un error similar al siguiente:

_api_windows_active (unimplemented_constructs:2:3)

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

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

unimplemented_constructs:2 (_api_windows_active)

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

Tipos de errores

Puedes corregir la mayoría de los errores que encuentras 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 sin implementar

Una API sin implementar 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, en su lugar, se podría agregar la API no implementada al archivo variant_resolution.gs.

En el informe de compatibilidad que generaste antes de la conversión, esta API está etiquetada como Se necesita más investigación.

Si no corriges este tipo de API en tu código VBA antes de convertir el archivo, la siguiente información se verá 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 API no implementados

Define la API no implementada con las APIs de Apps Script o las bibliotecas de 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. Sobre 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 encuentras una manera de implementar la API en Apps Script, considera 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 podrás convertirla.

Ejemplos de errores de API no implementados

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

  • No hay 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 pueda volver a crear en Apps Script.
Ejemplo 1: Sin Apps Script o API desconocida 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 para proteger el 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, se agrega el error de la API no implementada al archivo variant_resolution.gs. En el siguiente ejemplo, se amplía el ejemplo anterior de la API de name() de VBA. 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. Como el código convertido no puede determinar el tipo de objeto exacto en el que se llama a name(), Macro Converter crea una nueva función 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 de name(). A continuación, se muestra el código de 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 de Apps Script convertido 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 VBA:

PrintName Application.CommandBars.item("Standard")
CommandBar no es compatible con Apps Script y, por lo tanto, tampoco se admiten los dos métodos utilizados en el código VBA anterior.
  • Application.CommandBars(): En VBA, se muestra una lista de todos los objetos CommandBar.
  • CommandBars.item(): En VBA, esto 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 las nuevas funciones funcionen, sigue estos pasos:

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

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

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 nuevo tipo de objeto. 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(), _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 implementado

  1. Actualiza el 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ízala de una manera que no requiera la construcción de lenguaje no compatible.
  4. Si no puedes encontrar una manera de reescribir tu 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 implementado

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

Ejemplo 1: Reemplaza GoTo por While Loop

Código de VBA original
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 un bucle For

Código de VBA original
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

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

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

  • xlLegendPositionBottom: Coloca la leyenda en la parte inferior del gráfico.
  • xlLegendPositionCorner: Coloca la leyenda en la esquina del gráfico.
  • xlLegendPositionCustom: Coloca 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 valores no admitidos de APIs parcialmente compatibles 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 creará una función de controlador de errores, _handle_<API_name>_error, en el archivo unimplemented_constructs.gs.

La función muestra un error de usuario y no reemplazará el valor por uno 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);
}

Corrige errores de la 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 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 un reemplazo adecuado.
  4. Actualiza la función _handle_<API_name>_error para que muestre un valor compatible en su lugar.
  5. Si no encuentras una forma de reemplazar el valor no admitido, no podrás convertir esta macro.

Ejemplo de un error de API parcialmente admitido

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

A continuación, se muestra un ejemplo de código VBA original que usa un valor no compatible: 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);
}

Se requiere trabajo manual

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, la siguiente información se verá 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.");
}

Corrige los errores de trabajo manual necesario

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 sobre la función para comprender qué APIs se pueden usar como solución alternativa. 1. Si no puedes encontrar una solución alternativa adecuada, considera quitar la API de tu código. 1. Si no encuentras una solución alternativa o no puedes quitar esta API de tu código y la macro arroja un error, no podrás convertirla.

Ejemplos de errores de trabajo manual necesario

A continuación, se incluyen ejemplos de APIs que arrojan errores de trabajo manual necesario y cómo corregirlos:

Ejemplo 1: Autocorrect.Addreplacement

En el siguiente ejemplo, el Autocorrect.Addreplacement de la API de VBA se puede convertir, pero 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 basado en una ruta de archivo.

Supongamos que hay dos archivos que abre workbook.open() en el código de 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() con Apps Script en cualquier lugar en que se use 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 '';
}

Según lo que indican 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 de las hojas de cálculo de Google correspondientes 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

Se agregan errores intencionales al código convertido para imitar el comportamiento de error del código 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 se muestra como indefinido.

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

Este ejemplo se muestra en el siguiente código:

Código de VBA original
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Código de Apps Script convertido (antes de que se agregue un 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 el 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));