변환된 코드의 오류 수정

매크로 변환기 부가기능은 대부분의 변환 프로세스를 자동화하지만 코드를 완료하려면 일부 API와 기타 항목을 조정해야 할 수 있습니다.

이 가이드를 사용하여 프로젝트에 추가된 Apps Script 파일 (GS 파일)을 이해하고, 다양한 오류 유형을 해석하고, 오류 수정 방법을 알아보세요.

프로젝트에 추가된 Apps Script 파일 이해하기

추가 GS 파일이 Apps Script 프로젝트에 추가되어 다음 작업에 도움이 됩니다.

  • Apps Script에 없는 VBA 상수와 값을 정의합니다.
  • 변환되지 않은 API를 구현합니다.
  • 변이를 해결합니다.

다음 GS 파일이 Apps Script 프로젝트에 추가됩니다.

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

Library.gs

일반적으로 library.gs 파일의 아무것도 수정할 필요가 없습니다.

library.gs 파일은 VBA 코드에 사용되었지만 Apps Script에는 없는 함수와 상수를 정의합니다. 이렇게 하면 새 Apps Script 코드가 VBA 코드와 더 비슷해집니다. 또한 library.gs 파일의 함수나 상수가 사용될 때마다 정의를 반복할 필요가 없습니다.

Unimplemented_constructs.gs

unimplemented_constructs.gs 파일은 매크로 변환기를 통해 변환할 수 없는 구조체 또는 API를 처리합니다. 코드가 의도한 대로 작동하도록 하려면 이 파일을 수정해야 할 수 있습니다.

예: Window.Activate()

다음은 Window.Activate()라는 지원되지 않는 API의 예입니다. 매크로 변환기가 비슷한 이름의 새로운 Apps Script 함수를 만들어 unimplemented_constructs.gs 파일에 정의합니다. VBA 함수가 지원되지 않으므로 새 Apps Script 함수에서 예외가 발생합니다.

원본 API가 VBA 코드에서 사용된 모든 곳에서 변환된 Apps Script 코드에 새로운 함수가 추가됩니다.

원래 API의 동작을 다시 만들 수 있는 해결 방법을 찾은 경우 unimplemented_constructs.gs 파일의 함수 정의만 업데이트하면 됩니다. 여기에 함수가 정의되면 Apps Script 프로젝트에서 함수가 표시되는 모든 곳에 함수가 적용됩니다.

다음은 코드의 예입니다.

원본 VBA 코드

Window.activate()

변환된 Apps Script 코드, 인라인으로 추가됨

_api_window_activate();

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

객체의 유형을 확인할 수 없는 경우 variant_resolutions.gs 파일이 Apps Script ���로젝트에 추가됩니다. 이는 여러 가지 이유(예: API에 여러 반환 유형이 있거나 객체가 그 자체로 선언됨)로 선언될 수 있습니다.

매크로 변환기는 문제의 API를 대체하고 객체 유형을 결정하는 데 도움이 되는 __handle_resolve_<api>()이라는 새 함수를 이 파일에 추가합니다.

경우에 따라 __handle_resolve_<api>() 함수를 업데이트하여 객체 유형을 수동으로 선언해야 할 수 있습니다. 지원되지 않는 객체 유형을 참고하세요.

예: name()

VBA의 여러 객체 유형은 name() API를 정의합니다. 일반적으로 Apps Script는 getName()이지만 모든 객체 유형에 상응하는 것은 아닙니다. 다음과 같이 여러 대체 사례가 발생할 수 있습니다.

  • 객체의 해당 API는 getName()와 다른 것으로 호출됩니다.
  • 객체에 이름을 가져올 Apps Script API가 없습니다.
  • 이에 상응하는 Apps Script 객체가 없습니다.

객체 유형이 결정되지 않으면 매크로 변환기는 variant_resolutions.gs 파일에 __handle_resolve_name라는 새 함수를 만듭니다.

다음은 코드의 예입니다.

원본 VBA 코드

a = Selection.name

이 경우 API name()는 현재 선택에서 호출됩니다. 시트 객체나 도형 객체를 선택할 수 있습니다. 시트 객체인 경우 변환은 getName()이지만 도형 객체인 경우 Apps Script에는 이에 상응하는 변환이 없습니다.

변환된 Apps Script 코드, 인라인으로 추가됨

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

아래의 __handle_resolve_name() 함수는 variant_resolution.gs 파일에 추가되어 다양한 객체 유형을 해결합니다. 이 함수는 객체 유형을 확인한 후 지원되는 경우 getName()를 사용하고 getName()가 지원되지 않는 경우 오류를 생성합니다.

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

오류 찾기

변환된 Apps Script 코드에서 오류가 발생하면 메시지에 오류 유형과 위치가 표시됩니다. 오류 메시지의 형식은 사용 중인 Apps Script 런타임에 따라 다릅니다.

기본 V8 런타임의 경우 다음과 같은 오류가 표시됩니다.

_api_windows_active (unimplemented_constructs:2:3)

즉, unimplemented_constructs.gs 파일의 2행 문자 3에 오류가 있습니다.

지원 중단된 Rhino 런타임을 사용하는 경우 다음과 같은 오류가 표시됩니다.

unimplemented_constructs:2 (_api_windows_active)

즉, 2행의 unimplemented_constructs.gs 파일에 오류가 있습니다.

오류 유형

위에 설명된 unimplemented_constructs.gsvariant_resolution.gs 파일에서 발생하는 대부분의 오류를 수정할 수 있습니다.

발생할 수 있는 오류 유형은 다음과 같습니다.

구현되지 않은 API

구현되지 않은 API는 매크로 변환기가 VBA에서 Apps Script로 변환할 수 없는 API이며 이 API의 알려진 해결 방법이 없습니다.

구현되지 않은 API는 일반적으로 빈 함수로(때로는 빈 서명 사용) unimplemented_constructs.gs 파일에 추가됩니다. 객체 유형을 확인할 수 없는 경우에는 구현되지 않은 API를 variant_resolution.gs 파일에 대신 추가할 수 있습니다.

전환 전에 생성한 호환성 보고서에서 이 API는 추가 조사 필요로 표시됩니다.

파일을 변환하기 전에 VBA 코드에서 이 유형의 API를 수정하지 않으면 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.");
}

구현되지 않은 API 오류 수정

기존 Apps Script API 또는 JS 라이브러리로 구현되지 않은 API를 정의합니다. 힙 덤프를 분석하려면 다음 단계를 따르세요.

  1. 오류가 발생한 위치에서 변환된 Apps Script 코드를 엽니다. 오류 찾기를 참고하세요.
  2. 함수 위에서 추가된 주석을 읽습니다. 경우에 따라 주석에서 Apps Script에서 API를 구현하는 방법을 제안합니다.
  3. Apps Script에서 API를 구현하는 방법을 찾을 수 없다면 코드에서 삭제해 보세요.
  4. 해결 방법을 찾을 수 없거나 코드에서 이 API를 삭제할 수 없어 매크로에서 이 오류가 발생하면 이 매크로를 변환할 수 없습니다.

구현되지 않은 API 오류의 예

다음은 구현되지 않은 API 시나리오의 예와 이를 해결하는 방법입니다.

  • 동등한 Apps Script 없음: Apps Script에 없는 API인 Chart.Protect의 간접적인 해결 방법을 보여줍니다.
  • 알 수 없는 객체 유형: 변수인 객체 유형을 처리하는 방법과 Apps Script에서 다시 만들 수 있는 지원되지 않는 객체 유형을 구현하는 방법을 보여줍니다.
예 1: 동등한 Apps Script 또는 알 수 없는 API 없음

이 예에서는 Google Sheets에서 차트를 보호할 방법이 없으므로 Chart.Protect가 자동으로 변환되지 않았습니다.

/**
* 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.');
}
차트를 보호할 수는 없지만 차트의 데이터 범위를 보호하여 데이터를 변경할 수 없도록 할 수 있습니다.

범위를 보호하는 샘플 구현은 다음과 같습니다.
/**
* 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();
}
}
예 2: 지원되지 않는 객체 유형

객체 유형을 알 수 없는 경우 구현되지 않은 API 오류가 variant_resolution.gs 파일에 추가됩니다. 다음 예는 위의 VBA name() API 예를 확장합니다. variant_resolution.gs를 참고하세요.

이 예에서 학습할 내용은 다음과 같습니다.

  1. name() API가 variant_resolution.gs 파일의 새 함수로 변환되는 방법.
  2. 변환된 코드에서 새 함수가 호출되는 방법
  3. Apps Script에서 지원되지 않는 객체 유형인 CommandBar의 해결 방법을 만드는 방법

1. 변환된 코드는 name()가 호출되는 정확한 객체 유형을 확인할 수 없으므로 Macro Converter는 아래와 같이 __handle_resolve_name라는 새 함수를 만듭니다.

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. VBA 코드가 name() API를 호출하는 PrintName() 함수를 정의한다고 가정해 보겠습니다. VBA 코드는 다음과 같습니다.

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
`name()` 은 변수인 객체에서 호출되므로 변환된 코드는 변환 시점의 객체 유형을 알지 못합니다. 변환된 Apps Script 코드는 `__handle_resolve_name` 함수를 호출합니다.
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

3. VBA 코드가 객체 유형 CommandBar에서 PrintName() 함수를 호출한다고 가정해 보겠습니다. VBA 코드는 다음과 같습니다.

PrintName Application.CommandBars.item("Standard")
CommandBar는 Apps Script에서 지원되지 않으므로 위의 VBA 코드에 사용된 두 가지 메서드도 지원되지 않습니다.
  • Application.CommandBars(): VBA에서 모든 CommandBar 객체의 목록을 반환합니다.
  • CommandBars.item(): VBA에서 특정 CommandBar 객체를 반환합니다.
이 객체 유형은 Apps Script에서 지원되지 않으므로 변환된 코드는 사용자가 정의해야 하는 `unimplementationed_structures.gs` 파일에 다음 함수를 생성합니다.
  • _api_application_commandbars()
  • _api_commandbars_item()
함수는 아래와 같이 변환된 코드에서 호출됩니다.
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.');
}

새 함수를 사용하려면 다음 단계를 따르세요.

3.1 CommandBars의 기능을 생성하는 새로운 객체 유형과 VBA에 있는 것과 유사한 새 CommandBars 컬렉션을 정의합니다.

3.2 새 객체 유형에 getName() 메서드를 추가합니다.

아래 코드는 3.1단계와 3.2단계를 보여줍니다. 메뉴 객체는 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 새 객체 유형을 처리하도록 variant_resolution.gs 파일에서 __handle_resolve_name 함수를 수정합니다. 아래와 같이 함수에 섹션을 추가합니다.

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 unimplemented_constructs.gs 파일에서 생성된 두 함수(_api_application_commandbars(), _api_commandbars_item())를 정의합니다. 이 단계에서는 함수의 원래 호출이 작동하는지 확인합니다.

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

구현되지 않은 언어 구성

construct는 실행 흐름 또는 데이터 표시를 제어하는 ���드 언어의 요소입니다. 예: 루프, 라벨, 이벤트, goto 모든 VBA 구성의 목록을 참고하세요.

매크로 변환기가 변환할 수 없는 구문은 구현되지 않은 언어 구성으로 간주됩니다.

매크로 변환기가 구현되지 않은 언어 구성이 있다고 판단하는 경우 TODO 주석을 삽입합니다.

다음 VBA 구성은 지원되지 않습니다.

구현되지 않은 언어 구성 오류 수정

  1. 로직이 지원되지 않는 언어 구성을 사용하지 않도록 코드를 업데이트합니다.
  2. 오류가 발생한 위치에서 변환된 Apps Script 코드를 엽니다. 오류 찾기를 참고하세요.
  3. 코드의 로직에 따라 지원되지 않는 언어 구성이 필요하지 않은 방식으로 업데이트합니다.
  4. 지원되지 않는 언어 구성 없이 코드를 다시 작성할 방법을 찾을 수 없는 경우 이 매크로를 변환할 수 없습니다.

구현되지 않은 언어 구성 오류의 예

가장 일반적인 구현되지 않은 언어 구성 중 하나는 GoTo 문입니다. 일부 VBA GoTo 문을 루프로 바꿀 수 있습니다. 다음은 GoTo 문 대신 루프를 사용하는 두 가지 예입니다.

예 1: GoToWhile Loop로 바꾸기

원본 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
동등한 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);
}

예 2: GoTo를 For Loop로 대체

원본 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
동등한 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

부분적으로 지원되는 API의 경우 일부 입력 매개변수는 Apps Script에서 지원되지만 지원되지 않는 경우도 있습니다.

예를 들어 VBA API legend_position는 Excel 그래프에서 범례를 정의하는 데 사용됩니다. 다음을 포함한 여러 유형의 입력 값을 지원합니다.

  • xlLegendPositionBottom: 차트 하단에 범례를 배치합니다.
  • xlLegendPositionCorner: 차트 모서리에 범례를 배치합니다.
  • xlLegendPositionCustom: 차트의 맞춤 위치에 범례를 배치합니다.

Apps Script에는 이러한 값 중 일부만 지원하는 동일한 코드가 있습니다. 다음 값은 지원되지 않습니다.

  • xlLegendPositionCorner
  • xlLegendPositionCustom

변환된 코드에서 부분적으로 지원되는 API의 지원되지 않는 값을 플래그하기 위해 이러한 값을 확인하는 library.gs 파일에 유효성 검사 조건이 추가됩니다. 예를 들면 다음과 같습니다.

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

유효성 검사 조건이 지원되지 않는 값 중 하나를 찾으면 오류 핸들러 함수 _handle_<API_name>_errorunimplemented_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);
}

부분적으로 지원되는 API 오류 수정

_handle_<API_name>_error 함수를 정의하여 지원되지 않는 값을 필요에 따라 허용되는 해결 방법으로 바꿉니다.

  1. 오류가 발생한 위치에서 변환된 Apps Script 코드를 엽니다. 오류 찾기를 참고하세요.
  2. 함수 위의 설명을 읽고 지원되는 값과 지원되지 않는 값을 파악합니다.
  3. 지원되지 않는 값의 경우 적합한 대체 값으로 사용할 수 있는 지원 값을 결정합니다.
  4. 대신 지원되는 값을 반환하도록 _handle_<API_name>_error 함수를 업데이트합니다.
  5. 지원되지 않는 값을 대체할 방법을 찾을 수 없는 경우 이 매크로를 변환할 수 없습니다.

부분적으로 지원되는 API 오류의 예

다음 예는 위에 언급된 VBA API legend_position를 확장합니다. 부분적으로 지원되는 API를 참고하세요.

다음은 지원되지 않는 값 xlLegendPositionCustom를 사용하는 원본 VBA 코드의 예입니다.

Charts(1).Legend.Position = xlLegendPositionCustom

매크로 변환기는 아래 함수를 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);
}

수동 작업 필요

수동 작업 필요는 VBA API를 Apps Script로 변환할 수 있지만 해결 방법이 필요하다는 의미입니다.

변환 전에 생성한 호환성 보고서에서 이 유형의 API는 해결 방법으로 지원됨으로 라벨이 지정됩니다.

파일을 변환하기 전에 VBA 코드에서 이 유형의 API를 수정하지 않으면 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.");
}

수동 작업 필요 오류 해결

API가 의도한 대로 작동하도록 API의 해결 방법을 구현합니다. 1. 오류가 발생한 위치에서 변환된 Apps Script 코드를 엽니다. 오류 찾기를 참고하세요. 1. 함수 위의 주석을 읽고 해결 방법으로 사용할 수 있는 API를 알아보세요. 1. 적절한 해결 방법을 찾을 수 없으면 코드에서 API를 삭제하는 것이 좋습니다. 1. 해결 방법을 찾을 수 없거나 코드에서 이 API를 삭제할 수 없고 매크로에서 오류가 발생하는 경우 이 매크로를 변환할 수 없습니다.

수동 작업 필요 오류의 예

다음은 수동 작업 필요 오류를 발생시키는 API의 예와 수정 방법입니다.

예시 1: Autocorrect.Addreplacement

다음 예에서는 VBA API Autocorrect.Addreplacement를 변환할 수 있지만 해결 방법이 필요합니다. 매크로 변환기는 코드 주석에서 함수를 구현하는 방법을 제안합니다.

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

}

Autocorrect.Addreplacement API 구현은 아래와 같습니다.

var AUTO_CORRECTIONS = "AUTO_CORRECTIONS";
// Need to get the autocorrections set in previous sessions and use them.
var savedAutoCorrections = PropertiesService.getDocumentProperties().getProperty(AUTO_CORRECTIONS);
var autoCorrections = savedAutoCorrections ? JSON.parse(savedAutoCorrections) : {};
function onEdit(e) {
autoCorrect(e.range);
}
function autoCorrect(range) {
for (key in autoCorrections) {
// Replace each word that needs to be auto-corrected with their replacements.
range.createTextFinder(key)
.matchCase(true)
.matchEntireCell(false)
.matchFormulaText(false)
.useRegularExpression(false)
.replaceAllWith(autoCorrections[key]);
}
}
/**
* Could not convert autocorrect.addreplacement API. Please add relevant code in
* the following function to implement it.
* This API has been used at the following locations in the VBA script.
* sheet1 : line 3
*
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : createTextFinder , onEdit
* Apps Script documentation links : https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit ,
createTextFinder
* Comments : AutoCorrect.AddReplacement was not converted, but there is an
* equivalent option you can implement manually. Use onEdit and FindReplaceRequest
* APIs instead, see https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* and createTextFinder. For more information on API manual implementation, see
* https://developers.google.com/apps-script/guides/macro-converter/fix-conversion-errors.
*
* @param {Object} CallingObject represents the parent object using which the API has been called.
* @param {string} What
* @param {string} Replacement
*
* @return {string}
*/

function _api_autocorrect_addreplacement(CallingObject, What, Replacement) {
autoCorrections[What] = Replacement;
// Store the updated autoCorrections in the properties so that future executions use the correction.
PropertiesService.getDocumentProperties().setProperty(AUTO_CORRECTIONS, JSON.stringify(autoCorrections));
}

예시 2: Workbook.open()

VBA API workbook.open()는 파일 경로를 기반으로 ���컬 파일을 엽니다.

VBA 코드의 workbook.open()로 다음 2개의 파일이 열려 있다고 가정해 보겠습니다.

  • 파일 1: C:\Data\abc.xlsx
  • 파일 2: C:\Data\xyz.xlsx

아래는 파일 1을 열 때 Workbook.open()를 사용하는 모든 위치에서 매크로 변환기가 Workbook.open()를 Apps Script로 대체하는 방법을 보여줍니다.

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
아래 오류는 Apps Script 프로젝트의 unimplemented_constructs.gs 파일에 추가됩니다.
/**
* 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 '';
}

위 샘플의 주석에 따라 대상 파일을 Google Drive의 Google Sheets 파일로 변환해야 합니다.

해당 Google Sheets ID는 아래에서 굵게 표시되어 있습니다.

  • 파일 #1: C:\Data\abc.xlsxhttps://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc 가 됩니다.
  • 파일 #2: C:\Data\abc.xlsxhttps://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ 가 됩니다.

그런 다음 아래와 같이 Apps Script 함수에서 코드를 수정하여 ID로 파일을 엽니다.

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

의도적인 오류

원본 VBA 코드의 오류 동작을 모방하기 위해 변환된 코드에 의도적 오류가 추가됩니다. 이러한 오류는 수정할 필요가 없습니다.

의도적인 오류의 예

VBA에서 배열의 경계를 넘어 요소에 액세스하려고 하면 코드에서 예외가 발생합니다. Apps Script에서 코드가 정의되지 않음을 반환합니다.

예기치 않은 결과를 방지하기 위해 Macro Converter는 개발자가 배열의 경계를 넘어 요소에 액세스하려고 할 때 예외를 발생시키는 Apps Script 코드를 추가합니다.

이 예는 아래 코드에 나와 있습니다.

원본 VBA 코드
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
변환된 Apps Script 코드 (예외 오류가 추가되기 전)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
예외 오류를 발생시키기 위해 Apps Script 코드가 추가됨
/**
* 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));