Corrigir erros no código convertido

O complemento Macro Converter automatiza a maior parte do processo de conversão, mas pode ser necessário fazer ajustes em algumas APIs e outros itens para finalizar o código.

Use este guia para entender os arquivos do Apps Script (arquivos GS) adicionados ao seu projeto, interpretar os diferentes tipos de erros e aprender a corrigi-los.

Noções básicas sobre os arquivos do Apps Script adicionados ao seu projeto

Outros arquivos GS são adicionados ao seu projeto do Apps Script para ajudar a:

  • Defina constantes e valores de VBA que não existem no Apps Script.
  • Implementar APIs não convertidas
  • Resolver variantes.

Os seguintes arquivos do GS são adicionados ao seu projeto do Apps Script:

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

Library.gs

Em geral, não é necessário modificar nada no arquivo library.gs.

O arquivo library.gs define funções e constantes usadas no código VBA que não existem no Apps Script. Isso ajuda o novo código do Apps Script a lembrar melhor o código VBA. Além disso, não é necessário repetir definições sempre que funções ou constantes do arquivo library.gs forem usadas.

Unimplemented_constructs.gs

O arquivo unimplemented_constructs.gs aborda construções ou APIs que não foram convertidas pelo Macro Converter. Você provavelmente precisa modificar esse arquivo para que seu código funcione conforme esperado.

Exemplo: Window.Activate()

Confira a seguir o exemplo de uma API sem suporte chamada Window.Activate(). O Macro Converter cria uma nova função do Apps Script com um nome semelhante e a define no arquivo unimplemented_constructs.gs. Como não há suporte para a função VBA, a nova função do Apps Script gera uma exceção.

A nova função é adicionada ao código convertido do Apps Script em todos os lugares em que a API original foi usada no código VBA.

Se você encontrar uma solução alternativa para recriar o comportamento da API original, basta atualizar a definição da função no arquivo unimplemented_constructs.gs. Depois que a função é definida, ela é aplicada a todos os lugares em que a função aparece no projeto do Apps Script.

Confira o exemplo no código:

Código VBA original

Window.activate()

Código do Apps Script convertido, adicionado imediatamente

_api_window_activate();

Definição da função adicionada ao arquivo 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

O arquivo variant_resolutions.gs será adicionado ao seu projeto do Apps Script se não for possível determinar o tipo de um objeto. Isso pode acontecer por vários motivos, como uma API com vários tipos de retorno ou o próprio objeto ser declarado como uma variante.

O Macro Converter adiciona uma nova função a esse arquivo chamada __handle_resolve_<api>(), que substitui a API em questão e ajuda a determinar o tipo de objeto.

Em alguns casos, pode ser necessário atualizar a função __handle_resolve_<api>() para declarar manualmente o tipo de objeto. Consulte Tipo de objeto incompatível.

Exemplo: name()

Muitos tipos de objeto no VBA definem uma API name(). Normalmente, o equivalente do Apps Script é getName(), mas não para cada tipo de objeto. Vários casos alternativos podem ocorrer:

  • A API equivalente do objeto tem um nome diferente de getName().
  • O objeto não tem uma API Apps Script para receber o nome.
  • Não há um objeto do Apps Script equivalente.

Quando o tipo de objeto não é determinado, o Macro Converter cria uma nova função com o nome __handle_resolve_name no arquivo variant_resolutions.gs.

Confira o exemplo no código:

Código VBA original

a = Selection.name

Nesse caso, a API name() é chamada na seleção atual. A seleção pode ser um objeto "Página" ou "Forma". Se for um objeto das Planilhas, a tradução será getName(). No entanto, se for um objeto Shape, não haverá equivalente no Apps Script.

Código do Apps Script convertido, adicionado imediatamente

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

A função __handle_resolve_name() abaixo é adicionada ao arquivo variant_resolution.gs para resolver diferentes tipos de objetos. A função verifica o tipo de objeto e, em seguida, usa getName() se tiver suporte ou gera um erro se getName() não for compatível.

Definição da função adicionada ao arquivo 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;
}

Encontrar erros

Quando você encontra um erro no código convertido do Apps Script, a mensagem especifica o tipo de erro e a localização dele. O formato da mensagem depende do ambiente de execução do Apps Script usado.

Se você estiver no ambiente de execução padrão do V8, um erro semelhante a este será exibido:

_api_windows_active (unimplemented_constructs:2:3)

Isso significa que o erro está localizado no arquivo unimplemented_constructs.gs na linha 2, caractere 3.

Se você estiver usando o ambiente de execução descontinuado do Rhino, vai encontrar um erro parecido com este:

unimplemented_constructs:2 (_api_windows_active)

Isso significa que o erro está localizado no arquivo unimplemented_constructs.gs na linha 2.

Tipos de erro

É possível corrigir a maioria dos erros encontrados nos arquivos unimplemented_constructs.gs e variant_resolution.gs descritos acima.

Os tipos de erro que podem ser encontrados incluem:

API não implementada

Uma API não implementada é uma API que o Macro Converter não consegue converter de VBA em Apps Script e não há uma solução alternativa conhecida para a API.

As APIs não implementadas geralmente são adicionadas ao arquivo unimplemented_constructs.gs como funções vazias (às vezes com assinaturas vazias). Se não for possível determinar o tipo de objeto, a API não implementada poderá ser adicionada ao arquivo variant_resolution.gs.

No relatório de compatibilidade gerado antes da conversão, essa API é rotulada como Precisa de mais investigação.

Se você não corrigir esse tipo de API no código VBA antes de converter o arquivo, veja como ele aparece no projeto do 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.");
}

Corrigir erros de API não implementados

Defina a API não implementada com as APIs do Apps Script ou as bibliotecas JS. Para isso, siga estas etapas:

  1. Abra o código convertido do Apps Script no local do erro. Consulte Encontrar erros.
  2. Acima da função, leia o comentário adicionado. Em alguns casos, o comentário sugere como implementar a API no Apps Script.
  3. Se você não encontrar uma maneira de implementar a API no Apps Script, considere removê-la do código.
  4. Se você não encontrar uma solução alternativa ou remover essa API do código e a macro gerar esse erro, não será possível converter a macro.

Exemplos de erros de API não implementados

Confira alguns exemplos de cenários de API não implementados e como corrigir:

  • Não há Apps Script equivalente: mostra uma solução indireta para Chart.Protect, uma API que não existe no Apps Script.
  • Um tipo de objeto desconhecido: mostra como lidar com um tipo de objeto que é uma variável e como implementar um tipo de objeto não compatível que pode ser recriado no Apps Script.
Exemplo 1: sem Apps Script equivalente ou API desconhecida

Neste exemplo, Chart.Protect não foi convertido automaticamente porque não há como proteger um gráfico nas Planilhas 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.');
}
Mesmo que não seja possível proteger um gráfico, você pode proteger o intervalo de dados dele para que os dados não possam ser alterados.

Um exemplo de implementação para proteger o intervalo é mostrado abaixo:
/**
* 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();
}
}
Exemplo 2: tipo de objeto incompatível

Quando o tipo de objeto é desconhecido, o erro de API não implementado é adicionado ao arquivo variant_resolution.gs. O exemplo a seguir expande o exemplo da API name() VBA acima. Confira variant_resolution.gs.

Neste exemplo, você vai aprender:

  1. Como a API name() é convertida em uma nova função no arquivo variant_resolution.gs.
  2. Como a nova função é chamada no código convertido.
  3. Como criar uma solução alternativa para CommandBar, um tipo de objeto sem suporte, no Apps Script.

1. Como o código convertido não pode determinar o tipo de objeto exato em que name() é chamado, o Macro Converter cria uma nova função chamada __handle_resolve_name, mostrada abaixo.

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. Suponha que o código VBA defina uma função PrintName() que chame a API name(). O código VBA é mostrado abaixo:

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
Como `name()` é chamado em um objeto que é uma variável, o código convertido não sabe o tipo de objeto no momento da conversão. O código convertido do Apps Script chamará a função "__handle_resolve_name":
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

3. Suponha que seu código VBA chame a função PrintName() no tipo de objeto CommandBar. O código VBA é mostrado abaixo:

PrintName Application.CommandBars.item("Standard")
CommandBar não é compatível com o Apps Script e, por isso, os dois métodos usados no código VBA acima também não são.
  • Application.CommandBars(): na VBA, isso retorna uma lista de todos os objetos CommandBar.
  • CommandBars.item(): na VBA, isso retorna um objeto CommandBar específico.
Como esse tipo de objeto não é compatível com o Apps Script, o código convertido cria as seguintes funções no arquivo "unimplemented_buildings.gs" que você precisa definir.
  • _api_application_commandbars()
  • _api_commandbars_item()
As funções são chamadas no código convertido, conforme mostrado abaixo:
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 as novas funções funcionem, siga estas etapas:

3.1 Defina um novo tipo de objeto que crie as funcionalidades de CommandBars e uma nova coleção de CommandBars semelhante ao que existe no VBA.

3.2 Adicionar um método getName() para o novo tipo de objeto.

As etapas 3.1 e 3.2 são mostradas no código abaixo. Os objetos de menu são criados como um novo tipo de objeto que imita o comportamento 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 Modifique a função __handle_resolve_name no arquivo variant_resolution.gs para processar o novo tipo de objeto. Adicione uma seção à função, conforme mostrado abaixo:

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 Defina as duas funções criadas no arquivo unimplemented_constructs.gs (_api_application_commandbars(), _api_commandbars_item()). Esta etapa garante que as chamadas originais da função funcionem.

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

Construções de linguagem não implementadas

Uma construct é um elemento da linguagem de código que controla o fluxo de execução ou a exibição de dados. Por exemplo, loops, identificadores, eventos e gotos. Veja uma lista de todas as construções do VBA.

Construções que o Macro Converter não consegue converter são consideradas construções de linguagem não implementadas.

Quando o Macro Converter determina que uma construção de linguagem não implementada existe, ele insere um comentário TODO.

As seguintes construções VBA não são compatíveis:

Corrigir erros de construção de linguagem não implementados

  1. Atualize o código para que sua lógica não dependa da construção de linguagem sem suporte.
  2. Abra o código convertido do Apps Script no local do erro. Consulte Localizar erros.
  3. Com base na lógica do código, atualize-o de forma que não exija a construção de linguagem sem suporte.
  4. Se você não conseguir reescrever o código sem a construção de linguagem sem suporte, não será possível converter essa macro.

Exemplos de erros de construção de linguagem não implementados

Uma das construções de linguagem não implementadas mais comuns é uma instrução GoTo. É possível substituir algumas instruções GoTo do VBA por repetições. Abaixo estão dois exemplos de uso de loops em vez de instruções GoTo.

Exemplo 1: substituir GoTo por While Loop

Código 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 ao 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);
}

Exemplo 2: substituir GoTo pela repetição "For"

Código 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 ao 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 compatível

Para APIs parcialmente compatíveis, alguns parâmetros de entrada são compatíveis com o Apps Script e outros não.

Por exemplo, a API VBA legend_position é usada para definir a legenda em um gráfico do Excel. Ele é compatível com vários tipos de valores de entrada, incluindo:

  • xlLegendPositionBottom: coloca a legenda na parte de baixo do gráfico.
  • xlLegendPositionCorner: coloca a legenda no canto do gráfico.
  • xlLegendPositionCustom: coloca a legenda em posições personalizadas no gráfico.

O Apps Script tem um código equivalente que aceita apenas alguns desses valores. Os valores abaixo não são compatíveis:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

Para sinalizar valores incompatíveis de APIs parcialmente compatíveis no código convertido, uma condição de validação é adicionada ao arquivo library.gs que verifica esses valores. Exemplo:

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

Se a condição de validação encontrar um dos valores não aceitos, uma função de gerenciador de erros, _handle_<API_name>_error, será criada no arquivo unimplemented_constructs.gs.

A função gera um erro de usuário e não substitui o valor por um valor compatível. Exemplo:

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

Corrigir erros de API parcialmente com suporte

Defina a função _handle_<API_name>_error para substituir os valores não aceitos por uma solução alternativa aceitável para suas necessidades.

  1. Abra o código convertido do Apps Script no local do erro. Consulte Encontrar erros.
  2. Leia o comentário acima da função para entender quais valores são aceitos e quais não são.
  3. Para os valores não compatíveis, determine quais valores compatíveis podem servir como uma substituição adequada.
  4. Atualize a função _handle_<API_name>_error para retornar um valor compatível.
  5. Se você não conseguir encontrar uma maneira de substituir o valor sem suporte, não será possível converter essa macro.

Exemplo de um erro de API parcialmente com suporte

O exemplo a seguir expande a API VBA legend_position mencionada acima. Consulte API parcialmente compatível.

Veja abaixo um exemplo de código VBA original que usa um valor sem suporte, xlLegendPositionCustom.

Charts(1).Legend.Position = xlLegendPositionCustom

O Macro Converter adiciona a função abaixo ao arquivo 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);
}

Trabalho manual necessário

Trabalho manual necessário significa que a API VBA pode ser convertida em Apps Script, mas precisa de uma solução alternativa.

No relatório de compatibilidade gerado antes da conversão, esse tipo de API é rotulado como Compatível com soluções alternativas.

Se você não corrigir esse tipo de API no código VBA antes de converter o arquivo, veja como ele aparece no projeto do 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.");
}

Corrigir erros de trabalho manual necessário

Implemente uma solução alternativa para que a API funcione conforme esperado. 1. Abra o código convertido do Apps Script no local do erro. Consulte Encontrar erros. 1. Leia o comentário acima da função para entender quais APIs podem ser usadas para uma solução alternativa. 1. Se você não encontrar uma solução alternativa adequada, considere remover a API do código. 1. Se você não conseguir encontrar uma solução alternativa ou remover essa API do código e a macro gerar um erro, não será possível converter essa macro.

Exemplos de erros de trabalho manual necessário

Confira alguns exemplos de APIs que geram erros de trabalho manual necessário e como corrigi-los:

Exemplo 1: Autocorrect.Addreplacement

No exemplo a seguir, a API VBA Autocorrect.Addreplacement pode ser convertida, mas precisa de uma solução alternativa. O Macro Converter sugere como implementar a função nos comentários do 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 implementação da API Autocorrect.Addreplacement é mostrada abaixo:

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

Exemplo 2: Workbook.open()

A API do VBA workbook.open() abre um arquivo local com base em um caminho de arquivo.

Suponha que haja dois arquivos sendo abertos por workbook.open() no código VBA:

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

Confira abaixo como o Macro Converter substitui Workbook.open() por Apps Script em todos os lugares em que Workbook.open() é usado para abrir o arquivo 1:

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
O erro abaixo é adicionado ao arquivo unimplemented_constructs.gs no projeto do 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 '';
}

Conforme as instruções dos comentários no exemplo acima, você precisa converter os arquivos de destino em arquivos do Planilhas Google no Google Drive.

Os IDs das Planilhas Google correspondentes estão em negrito abaixo:

  • Arquivo 1: C:\Data\abc.xlsx se torna https://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc
  • Arquivo 2: C:\Data\abc.xlsx se torna https://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ

Em seguida, modifique o código na função do Apps Script para abrir os arquivos por ID, conforme mostrado abaixo:

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

Erro intencional

Erros intencionais são adicionados ao código convertido para imitar o comportamento de erro do código VBA original. Não é necessário modificar esses erros.

Exemplo de um erro intencional

Se você tentar acessar um elemento além dos limites de uma matriz no VBA, o código gerará uma exceção. No Apps Script, o código retorna "undefined".

Para evitar resultados inesperados, o Macro Converter adiciona código do Apps Script que gera uma exceção quando você tenta acessar elementos além dos limites de uma matriz.

Esse exemplo é mostrado no código abaixo:

Código VBA original
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
Código do Apps Script convertido (antes que o erro de exceção seja adicionado)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
O código do Apps Script foi adicionado para gerar o erro de exceção
/**
* 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));