আপনার রূপান্তরিত কোডে ত্রুটি ঠিক করুন

ম্যাক্রো কনভার্টার গুগল ওয়ার্কস্পেস অ্যাড-অনটি রূপান্তর প্রক্রিয়ার বেশিরভাগ অংশ স্বয়ংক্রিয় করে, কিন্তু আপনার কোড চূড়ান্ত করার জন্য কিছু এপিআই এবং অন্যান্য আইটেমে সমন্বয় করার প্রয়োজন হতে পারে।

আপনার প্রজেক্টে যুক্ত করা অ্যাপস স্ক্রিপ্ট ফাইল (জিএস ফাইল) বুঝতে, বিভিন্ন ধরনের ত্রুটি ব্যাখ্যা করতে এবং ত্রুটি সমাধান করার পদ্ধতি শিখতে এই নির্দেশিকাটি ব্যবহার করুন।

আপনার প্রজেক্টে যোগ করা অ্যাপস স্ক্রিপ্ট ফাইলগুলো বুঝুন।

আপনার অ্যাপস স্ক্রিপ্ট প্রোজেক্টে সাহায্য করার জন্য অতিরিক্ত জিএস ফাইল যোগ করা হয়েছে:

  • অ্যাপস স্ক্রিপ্টে নেই এমন VBA কনস্ট্যান্ট এবং ভ্যালু সংজ্ঞায়িত করুন।
  • অপরিবর্তিত এপিআইগুলো বাস্তবায়ন করুন।
  • বৈকল্পিক রূপগুলি সমাধান করুন।

আপনার অ্যাপস স্ক্রিপ্ট প্রজেক্টে নিম্নলিখিত GS ফাইলগুলো যোগ করা হয়েছে:

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

Library.gs

সাধারণত, আপনার library.gs ফাইলে কোনো কিছু পরিবর্তন করার প্রয়োজন নেই।

` library.gs ফাইলটি আপনার VBA কোডে ব্যবহৃত এমন সব ফাংশন এবং কনস্ট্যান্ট সংজ্ঞায়িত করে, যেগুলো অ্যাপস স্ক্রিপ্টে নেই। এটি নতুন অ্যাপস স্ক্রিপ্ট কোডকে আপনার VBA কোডের সাথে আরও ভালোভাবে সাদৃশ্যপূর্ণ করতে সাহায্য করে। এছাড়াও, ` library.gs ফাইল থেকে ফাংশন বা কনস্ট্যান্ট প্রতিবার ব্যবহার করার সময় আপনাকে সেগুলোর সংজ্ঞা পুনরাবৃত্তি করতে হবে না।

Unimplemented_constructs.gs

unimplemented_constructs.gs ফাইলটিতে এমন সব কনস্ট্রাক্ট বা এপিআই-এর উল্লেখ রয়েছে, যেগুলো ম্যাক্রো কনভার্টার দ্বারা রূপান্তর করা যায়নি। আপনার কোডটি উদ্দেশ্য অনুযায়ী কাজ করানোর জন্য সম্ভবত এই ফাইলটি পরিবর্তন করতে হবে।

উদাহরণ: Window.Activate

নিচে Window.Activate নামক একটি অসমর্থিত API-এর উদাহরণ দেওয়া হলো। ম্যাক্রো কনভার্টারটি একই নামের একটি নতুন অ্যাপস স্ক্রিপ্ট ফাংশন তৈরি করে এবং এটিকে unimplemented_constructs.gs ফাইলে সংজ্ঞায়িত করে। যেহেতু VBA ফাংশনটি সমর্থিত নয়, তাই নতুন অ্যাপস স্ক্রিপ্ট ফাংশনটি একটি এক্সেপশন থ্রো করে।

রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডে, ভিবিএ কোডে যেখানে যেখানে মূল এপিআই ব্যবহার করা হয়েছিল, সেখানে নতুন ফাংশনটি যোগ করা হয়।

যদি আপনি মূল API-এর আচরণ পুনরায় তৈরি করার জন্য কোনো বিকল্প উপায় খুঁজে পান, তাহলে আপনাকে শুধু unimplemented_constructs.gs ফাইলে ফাংশনটির সংজ্ঞা আপডেট করতে হবে। একবার সেখানে ফাংশনটি সংজ্ঞায়িত করা হলে, আপনার Apps Script প্রোজেক্টে যেখানেই ফাংশনটি থাকবে, সেখানেই তা প্রযোজ্য হবে।

এখানে কোডে উদাহরণটি দেওয়া হলো:

আসল VBA কোড

Window.activate()

রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোড, ইন-লাইনে যোগ করা হয়েছে।

_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 ফাইলটি যুক্ত করা হয়। এটি বিভিন্ন কারণে ঘটতে পারে, যেমন কোনো API-এর একাধিক রিটার্ন টাইপ থাকা অথবা অবজেক্টটি নিজেই একটি ভ্যারিয়েন্ট হিসেবে ঘোষিত হওয়া।

ম্যাক্রো কনভার্টার এই ফাইলে __handle_resolve_<api> নামে একটি নতুন ফাংশন যোগ করে, যা সংশ্লিষ্ট API-টিকে প্রতিস্থাপন করে এবং অবজেক্টের ধরন নির্ধারণ করতে সাহায্য করে।

কিছু ক্ষেত্রে, অবজেক্ট টাইপটি ম্যানুয়ালি ঘোষণা করার জন্য আপনাকে __handle_resolve_<api> ফাংশনটি আপডেট করতে হতে পারে। অসমর্থিত অবজেক্ট টাইপ দেখুন।

উদাহরণ: name পদ্ধতি

VBA-তে অনেক অবজেক্ট টাইপ একটি name মেথড সংজ্ঞায়িত করে। সাধারণত, Apps Script-এ এর সমতুল্য হলো getName , কিন্তু সব অবজেক্ট টাইপের জন্য তা নয়। একাধিক বিকল্প পরিস্থিতি দেখা দিতে পারে:

  • অবজেক্টটির সমতুল্য মেথডটির নাম getName থেকে ভিন্ন।
  • অবজেক্টটির নাম পাওয়ার জন্য কোনো অ্যাপস স্ক্রিপ্ট এপিআই নেই।
  • এর কোনো সমতুল্য অ্যাপস স্ক্রিপ্ট অবজেক্ট নেই।

যখন অবজেক্টের ধরণ নির্ধারিত থাকে না, তখন ম্যাক্রো কনভার্টার variant_resolutions.gs ফাইলে __handle_resolve_name নামে একটি নতুন ফাংশন তৈরি করে।

এখানে কোডে উদাহরণটি দেওয়া হলো:

আসল VBA কোড

a = Selection.name

এক্ষেত্রে, বর্তমান নির্বাচিত অংশের উপর name মেথডটি কল করা হয়। নির্বাচিত অংশটি একটি Sheet অবজেক্ট বা একটি Shape অবজেক্ট হতে পারে। যদি এটি একটি Sheet অবজেক্ট হয়, তবে এর অনুবাদ হলো getName , কিন্তু যদি এটি একটি Shape অবজেক্ট হয়, তবে Apps Script-এ এর কোনো সমতুল্য নেই।

রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোড, ইন-লাইনে যোগ করা হয়েছে।

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

বিভিন্ন অবজেক্ট টাইপের সমাধান করার জন্য variant_resolution.gs ফাইলে নিম্নলিখিত __handle_resolve_name ফাংশনটি যোগ করা হয়েছে। ফাংশনটি অবজেক্ট টাইপ পরীক্ষা করে, তারপর 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;
}

ভুল খুঁজুন

রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডে কোনো ত্রুটি দেখা দিলে, বার্তাটিতে ত্রুটির ধরন এবং এর অবস্থান উল্লেখ করা থাকে। ত্রুটি বার্তার বিন্যাসটি নির্ভর করে আপনি কোন অ্যাপস স্ক্রিপ্ট রানটাইম ব্যবহার করছেন তার উপর।

আপনি যদি ডিফল্ট V8 রানটাইমে থাকেন, তাহলে নিচের মতো একটি ত্রুটি দেখতে পাবেন:

_api_windows_active (unimplemented_constructs:2:3)

এর মানে হলো, ত্রুটিটি unimplemented_constructs.gs ফাইলের ২ নং লাইনের ৩ নং ক্যারেক্টারে অবস্থিত।

আপনি যদি অপ্রচলিত রাইনো রানটাইমে থাকেন, তাহলে আপনি নিম্নলিখিতের মতো একটি ত্রুটি দেখতে পাবেন:

unimplemented_constructs:2 (_api_windows_active)

এর মানে হলো, ত্রুটিটি unimplemented_constructs.gs ফাইলের ২ নম্বর লাইনে অবস্থিত।

ত্রুটির প্রকারভেদ

পূর্বে বর্ণিত unimplemented_constructs.gs এবং variant_resolution.gs ফাইলগুলিতে আপনি যে ত্রুটিগুলির সম্মুখীন হন, তার বেশিরভাগই সমাধান করুন।

আপনি যে ধরনের ত্রুটির সম্মুখীন হতে পারেন, সেগুলো হলো:

অবাস্তবায়িত এপিআই

একটি অপ্রয়োগকৃত এপিআই হলো এমন একটি এপিআই, যা ম্যাক্রো কনভার্টার ভিবিএ থেকে অ্যাপস স্ক্রিপ্টে রূপান্তর করতে পারে না এবং যার জন্য কোনো পরিচিত বিকল্প সমাধান নেই।

যেসব এপিআই বাস্তবায়িত হয়নি, সেগুলোকে সাধারণত খালি ফাংশন হিসেবে—কখনও কখনও খালি সিগনেচার সহ— unimplemented_constructs.gs ফাইলে যোগ করা হয়। যদি অবজেক্টের ধরন নির্ধারণ করা না যায়, তবে বাস্তবায়িত না হওয়া এপিআই-টি এর পরিবর্তে variant_resolution.gs ফাইলে যোগ করা হতে পারে।

রূপান্তরের আগে আপনার তৈরি করা সামঞ্জস্যতা প্রতিবেদনে, এই API-টিকে 'আরও তদন্ত প্রয়োজন ' হিসেবে চিহ্নিত করা হয়েছে।

ফাইলটি রূপান্তর করার আগে আপনি যদি আপনার VBA কোডে এই ধরনের API ঠিক না করেন, তাহলে অ্যাপস স্ক্রিপ্ট প্রজেক্টে এটি দেখতে এইরকম হয়:

/**
* Could not convert . Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*      : 
* We couldn't find an equivalent API in Apps Script for this VBA API. Please
* reconsider if this function call is critical, otherwise consider implementing
* it in a different way.
* @param param1 {}
* @param param2 {}
* ...
* @return {}
*/
function _api_<API_name>(param1, param2, ....) {
  ThrowException("API  not supported yet.");
}

অবাস্তবায়িত API ত্রুটিগুলি ঠিক করুন

বিদ্যমান অ্যাপস স্ক্রিপ্ট এপিআই বা জেএস লাইব্রেরি ব্যবহার করে অব্যবহৃত এপিআইটি সংজ্ঞায়িত করুন। এটি করার জন্য, এই ধাপগুলো অনুসরণ করুন:

  1. ত্রুটির স্থানে রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডটি খুলুন। ত্রুটি খুঁজুন (Find errors) দেখুন।
  2. ফাংশনের উপরে যোগ করা মন্তব্যটি পড়ুন। কিছু ক্ষেত্রে, মন্তব্যটিতে অ্যাপস স্ক্রিপ্টে এপিআই (API) কীভাবে প্রয়োগ করতে হবে তার পরামর্শ দেওয়া থাকে।
  3. অ্যাপস স্ক্রিপ্টে এপিআইটি প্রয়োগ করার কোনো উপায় খুঁজে না পেলে, আপনার কোড থেকে এটি সরিয়ে ফেলার কথা বিবেচনা করতে পারেন।
  4. যদি আপনি কোনো বিকল্প সমাধান খুঁজে না পান অথবা আপনার কোড থেকে এই API-টি সরিয়ে না ফেলেন এবং আপনার ম্যাক্রোটি এই ত্রুটি দেখায়, তাহলে আপনি এই ম্যাক্রোটি রূপান্তর করতে পারবেন না।

বাস্তবায়িত না হওয়া API ত্রুটির উদাহরণ

এখানে বাস্তবায়িত না হওয়া API সিনারিওগুলির উদাহরণ এবং সেগুলি সমাধান করার উপায় দেওয়া হল:

  • এর কোনো সমতুল্য অ্যাপস স্ক্রিপ্ট নেই : এটি Chart.Protect এর জন্য একটি পরোক্ষ বিকল্প সমাধান দেখায়, যা অ্যাপস স্ক্রিপ্টে বিদ্যমান নেই এমন একটি API।
  • একটি অজানা অবজেক্ট টাইপ : এখানে দেখানো হয়েছে কীভাবে একটি ভেরিয়েবল হিসেবে ব্যবহৃত অবজেক্ট টাইপকে পরিচালনা করতে হয়, এবং কীভাবে একটি অসমর্থিত অবজেক্ট টাইপ প্রয়োগ করতে হয় যা অ্যাপস স্ক্রিপ্টে পুনরায় তৈরি করা যায়।
উদাহরণ ১: কোনো সমতুল্য অ্যাপস স্ক্রিপ্ট নেই অথবা এপিআই অজানা

এই উদাহরণে, 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();
}
}
উদাহরণ ২: অসমর্থিত অবজেক্ট টাইপ

যখন অবজেক্টের ধরন অজানা থাকে, তখন variant_resolution.gs ফাইলে অপ্রয়োগকৃত API ত্রুটিটি যোগ করা হয়। নিম্নলিখিত উদাহরণটি VBA name মেথড উদাহরণটির বিশদ ব্যাখ্যা দেয়। variant_resolution.gs দেখুন।

এই উদাহরণ থেকে আপনি শিখবেন:

  1. variant_resolution.gs ফাইলে কীভাবে name মেথডটিকে একটি নতুন ফাংশনে রূপান্তর করা হয়
  2. রূপান্তরিত কোডে নতুন ফাংশনটি কীভাবে কল করা হয়
  3. অ্যাপস স্ক্রিপ্টে CommandBar (একটি অসমর্থিত অবজেক্ট টাইপ)-এর জন্য কীভাবে একটি বিকল্প সমাধান তৈরি করবেন

যেহেতু রূপান্তরিত কোডটি ` name দ্বারা কল করা সঠিক অবজেক্ট টাইপটি নির্ধারণ করতে পারে না, তাই ম্যাক্রো কনভার্টার __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;
}

২. ধরা যাক, VBA কোডে একটি PrintName() ফাংশন সংজ্ঞায়িত করা আছে যা name API-কে কল করে:

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
যেহেতু `name()` ফাংশনটি এমন একটি অবজেক্টের উপর কল করা হয় যা একটি ভেরিয়েবল, তাই রূপান্তরের সময় রূপান্তরিত কোডটি অবজেক্টের টাইপ সম্পর্কে জানে না। রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডটি `__handle_resolve_name` ফাংশনটি কল করবে:
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

৩. ধরুন, আপনার VBA কোডটি CommandBar অবজেক্ট টাইপের উপর PrintName() ফাংশনটি কল করে:

PrintName Application.CommandBars.item("Standard")
অ্যাপস স্ক্রিপ্টে CommandBar সমর্থিত নয় এবং ফলস্বরূপ, উপরের ভিবিএ কোডে ব্যবহৃত দুটি পদ্ধতিও সমর্থিত নয়।
  • Application.CommandBars() : VBA-তে, এটি সমস্ত CommandBar অবজেক্টের একটি তালিকা ফেরত দেয়।
  • CommandBars.item() : VBA-তে, এটি একটি নির্দিষ্ট CommandBar অবজেক্ট রিটার্ন করে।
যেহেতু এই অবজেক্ট টাইপটি অ্যাপস স্ক্রিপ্টে সমর্থিত নয়, তাই রূপান্তরিত কোডটি `unimplemented_constructs.gs` ফাইলে নিম্নলিখিত ফাংশনগুলি তৈরি করে, যেগুলি আপনাকে সংজ্ঞায়িত করতে হবে।
  • _api_application_commandbars()
  • _api_commandbars_item()
রূপান্তরিত কোডে ফাংশনগুলোকে নিচে দেখানো পদ্ধতিতে কল করা হয়:
PrintName(_api_commandbars_item(_api_application_commandbars(), "Standard")))

Heres how the new functions are added to the unimplemented_construct.gs file:

function _api_application_commandbars(CallingObject) {
  ThrowException('API application.commandbars not supported yet.');
}
function _api_commandbars_item(CallingObject, index) {
  ThrowException('API commandbars.item not supported yet.');
}

নতুন ফাংশনগুলো চালু করতে, নিম্নলিখিত পদক্ষেপগুলো অনুসরণ করুন:

৩.১ একটি নতুন অবজেক্ট টাইপ সংজ্ঞায়িত করুন যা CommandBars কার্যকারিতা তৈরি করবে এবং ভিবিএ-তে বিদ্যমান CommandBars কালেকশন তৈরি করবে।

৩.২ নতুন অবজেক্ট টাইপটির জন্য একটি getName মেথড যোগ করুন।

ধাপ ৩.১ এবং ৩.২ নিম্নলিখিত কোডে দেখানো হয়েছে। মেনু অবজেক্টগুলো একটি নতুন অবজেক্ট টাইপ হিসেবে তৈরি করা হয় যা 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();

৩.৩ নতুন অবজেক্ট টাইপটি হ্যান্ডেল করার জন্য 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;
}

৩.৪ 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);
}

অবাস্তবায়িত ভাষা গঠন

কনস্ট্রাক্ট হলো কোড ল্যাঙ্গুয়েজের এমন একটি উপাদান যা কার্যপ্রবাহ বা ডেটা প্রদর্শন নিয়ন্ত্রণ করে। উদাহরণস্বরূপ, লুপ, লেবেল, ইভেন্ট এবং গো-টু। সমস্ত ভিবিএ কনস্ট্রাক্টের তালিকার জন্য, স্টেটমেন্টস (ভিবিএ) দেখুন।

যেসব গঠন ম্যাক্রো কনভার্টার রূপান্তর করতে পারে না, সেগুলোকে অপ্রয়োগকৃত ভাষা গঠন হিসেবে গণ্য করা হয়।

ম্যাক্রো কনভার্টার যখন কোনো অব্যবহৃত ল্যাঙ্গুয়েজ কনস্ট্রাক্টের অস্তিত্ব শনাক্ত করে, তখন এটি একটি TODO কমেন্ট যোগ করে।

নিম্নলিখিত VBA গঠনগুলি সমর্থিত নয়:

অবাস্তবায়িত ভাষা গঠনের ত্রুটিগুলি সংশোধন করুন

  1. আপনার কোডটি এমনভাবে আপডেট করুন যাতে এর লজিকটি কোনো অসমর্থিত ল্যাঙ্গুয়েজ কনস্ট্রাক্টের উপর নির্ভর না করে।
  2. ত্রুটির স্থানে রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডটি খুলুন। ত্রুটি খুঁজুন (Find errors) দেখুন।
  3. কোডের যুক্তির উপর ভিত্তি করে, এটিকে এমনভাবে আপডেট করুন যাতে অসমর্থিত ল্যাঙ্গুয়েজ কনস্ট্রাক্টের প্রয়োজন না হয়।
  4. যদি আপনি অসমর্থিত ল্যাঙ্গুয়েজ কনস্ট্রাক্টটি ছাড়া আপনার কোডটি পুনর্লিখন করার কোনো উপায় খুঁজে না পান, তাহলে আপনি এই ম্যাক্রোটি রূপান্তর করতে পারবেন না।

বাস্তবায়িত না হওয়া ভাষা গঠনগত ত্রুটির উদাহরণ

সবচেয়ে প্রচলিত কিন্তু অব্যবহৃত ল্যাঙ্গুয়েজ কনস্ট্রাক্টগুলোর মধ্যে একটি হলো GoTo স্টেটমেন্ট। কিছু VBA GoTo স্টেটমেন্টকে লুপ দিয়ে প্রতিস্থাপন করুন। নিচের উদাহরণগুলোতে GoTo স্টেটমেন্টের পরিবর্তে লুপ ব্যবহার করা হয়েছে।

উদাহরণ ১: GoTo While 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
সমতুল্য অ্যাপস স্ক্রিপ্ট কোড
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);
}

উদাহরণ ২: 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
সমতুল্য অ্যাপস স্ক্রিপ্ট কোড
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-গুলোর ক্ষেত্রে, অ্যাপস স্ক্রিপ্টে কিছু ইনপুট প্যারামিটার সমর্থিত হয় এবং কিছু হয় না।

উদাহরণস্বরূপ, এক্সেল গ্রাফের লিজেন্ড নির্ধারণ করতে VBA API ' legend_position ব্যবহার করা হয়। এটি বিভিন্ন ধরনের ইনপুট ভ্যালু সমর্থন করে, যার মধ্যে রয়েছে:

  • xlLegendPositionBottom : লিজেন্ডটিকে চার্টের একেবারে নিচে রাখে।
  • xlLegendPositionCorner : লিজেন্ডটিকে চার্টের কোণায় স্থাপন করে।
  • xlLegendPositionCustom : চার্টে লিজেন্ডকে নিজস্ব অবস্থানে স্থাপন করে।

অ্যাপস স্ক্রিপ্টে একটি সমতুল্য কোড আছে যা ওই মানগুলোর মধ্যে কেবল কয়েকটি সমর্থন করে। নিম্নলিখিত মানগুলো সমর্থিত নয়:

  • xlLegendPositionCorner
  • xlLegendPositionCustom

আপনার রূপান্তরিত কোডে আংশিকভাবে সমর্থিত API-এর অসমর্থিত মানগুলিকে চিহ্নিত করতে, library.gs ফাইলে একটি যাচাইকরণ শর্ত যোগ করা হয় যা সেই মানগুলি পরীক্ষা করে। উদাহরণস্বরূপ:

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

যদি যাচাইকরণ শর্তে কোনো অসমর্থিত মান পাওয়া যায়, তাহলে unimplemented_constructs.gs ফাইলে _handle_<API_name>_error নামে একটি ত্রুটি হ্যান্ডলার ফাংশন তৈরি করা হয়।

ফাংশনটি একটি ইউজার এরর দেখায় এবং ভ্যালুটিকে কোনো সাপোর্টেড ভ্যালু দিয়ে প্রতিস্থাপন করে না। উদাহরণস্বরূপ:

/**
* 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. ত্রুটির স্থানে রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডটি খুলুন। ত্রুটি খুঁজুন (Find errors) দেখুন।
  2. কোন মানগুলো সমর্থিত এবং কোনগুলো নয়, তা বোঝার জন্য ফাংশনের উপরের মন্তব্যটি পড়ুন।
  3. অসমর্থিত মানগুলোর ক্ষেত্রে, কোন সমর্থিত মানগুলো উপযুক্ত প্রতিস্থাপন হিসেবে কাজ করতে পারে তা নির্ধারণ করুন।
  4. _handle_<API_name>_error ফাংশনটিকে আপডেট করে একটি সমর্থিত মান রিটার্ন করার ব্যবস্থা করুন।
  5. যদি আপনি অসমর্থিত মানটি প্রতিস্থাপন করার কোনো উপায় খুঁজে না পান, তাহলে আপনি এই ম্যাক্রোটি রূপান্তর করতে পারবেন না।

আংশিকভাবে সমর্থিত এপিআই ত্রুটির একটি উদাহরণ

নিম্নলিখিত উদাহরণটি পূর্বে উল্লিখিত VBA API legend_position উপর বিস্তারিত আলোচনা করে। আংশিকভাবে সমর্থিত API দেখুন।

নিম্নলিখিত উদাহরণটি মূল VBA কোড দেখাচ্ছে যেখানে xlLegendPositionCustom নামক একটি অসমর্থিত মান ব্যবহার করা হয়েছে।

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-কে অ্যাপস স্ক্রিপ্টে রূপান্তর করা যেতে পারে, কিন্তু এর জন্য একটি বিকল্প পদ্ধতির প্রয়োজন।

রূপান্তরের আগে আপনার তৈরি করা সামঞ্জস্যতা প্রতিবেদনে, এই ধরনের API-কে ‘সমাধানসহ সমর্থিত’ হিসেবে চিহ্নিত করা হয়েছে।

ফাইলটি রূপান্তর করার আগে আপনি যদি আপনার VBA কোডে এই ধরনের API ঠিক না করেন, তাহলে অ্যাপস স্ক্রিপ্ট প্রজেক্টে এটি দেখতে এইরকম হয়:

/**
* Could not convert  API. Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*      : 
*
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : 
* Apps Script documentation links : 
*
* @param param1 {}
* @param param2 {}
* ...
* @return {}
*/
function _api_<API_name>(param1, param2, ....) {
 ThrowException("API  not supported yet.");
}

ম্যানুয়াল কাজের প্রয়োজনীয় ত্রুটিগুলি ঠিক করুন

এপিআই-কে উদ্দেশ্য অনুযায়ী কাজ করানোর জন্য একটি বিকল্প সমাধান (workaround) প্রয়োগ করুন। ১. ত্রুটির স্থানে রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোডটি খুলুন। 'ত্রুটি খুঁজুন' (Find errors ) দেখুন। ১. বিকল্প সমাধানের জন্য কোন এপিআইগুলো ব্যবহার করা যেতে পারে তা বোঝার জন্য ফাংশনের উপরের মন্তব্যটি পড়ুন। ১. যদি আপনি কোনো উপযুক্ত বিকল্প সমাধান খুঁজে না পান, তবে আপনার কোড থেকে এপিআইটি সরিয়ে ফেলার কথা বিবেচনা করুন। ১. যদি আপনি কোনো বিকল্প সমাধান খুঁজে না পান বা আপনার কোড থেকে এই এপিআইটি সরিয়ে ফেলার পরেও আপনার ম্যাক্রোতে ত্রুটি দেখা দেয়, তবে আপনি এই ম্যাক্রোটি রূপান্তর করতে পারবেন না।

ম্যানুয়াল কাজের প্রয়োজনীয়তার ত্রুটির উদাহরণ

এখানে এমন কিছু API-এর উদাহরণ দেওয়া হলো যেগুলো 'Manual work needed' ত্রুটি দেখায় এবং সেগুলো কীভাবে সমাধান করতে হয়:

উদাহরণ ১: 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));
}

উদাহরণ ২: Workbook.open পদ্ধতি

VBA API workbook.open একটি পাথের উপর ভিত্তি করে স্থানীয় ফাইল খোলে।

ধরা যাক, VBA কোডে workbook.open ব্যবহার করে দুটি ফাইল খোলা হচ্ছে:

  • ফাইল ১: C:\Data\abc.xlsx
  • ফাইল ২: C:\Data\xyz.xlsx

নিম্নলিখিত কোডটি দেখায় কিভাবে ম্যাক্রো কনভার্টারটি ফাইল ১ খোলার জন্য যেখানেই Workbook.open ব্যবহার করা হয়েছে Workbook.open সেখানে সেটিকে অ্যাপস স্ক্রিপ্ট দিয়ে প্রতিস্থাপন করে:

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
অ্যাপস স্ক্রিপ্ট প্রজেক্টের 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 '';
}

পূর্ববর্তী নমুনার মন্তব্যে দেওয়া নির্দেশনা অনুযায়ী, আপনাকে টার্গেট ফাইলগুলোকে ড্রাইভে শীটস ফাইলে রূপান্তর করতে হবে।

নিম্নলিখিত তালিকায় সংশ্লিষ্ট গুগল স্প্রেডশিট আইডিগুলো হাইলাইট করা হয়েছে:

  • ফাইল #১: C:\Data\abc.xlsx হয়ে যায় https://docs.google.com/spreadsheets/d/ abc123Abc123Abc123abc
  • ফাইল #২: C:\Data\xyz.xlsx ফাইলটি https://docs.google.com/spreadsheets/d/ xyz456Xyz456xYz456xyZ পরিণত হয়।

এরপর, আইডি দ্বারা ফাইলগুলো খোলার জন্য অ্যাপস স্ক্রিপ্ট ফাংশনের কোডটি পরিবর্তন করুন:

/**
* 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-তে অ্যারের সীমার বাইরের কোনো এলিমেন্ট অ্যাক্সেস করার চেষ্টা করলে, কোডটি একটি এক্সেপশন থ্রো করে। অ্যাপস স্ক্রিপ্টে, কোডটি 'undefined' রিটার্ন করে।

অপ্রত্যাশিত ফলাফল এড়ানোর জন্য, ম্যাক্রো কনভার্টারটি অ্যাপস স্ক্রিপ্ট কোড যোগ করে, যা অ্যারের সীমার বাইরের কোনো এলিমেন্ট অ্যাক্সেস করার চেষ্টা করলে একটি এক্সেপশন থ্রো করে।

এই উদাহরণটি নিম্নলিখিত কোডে দেখানো হয়েছে:

আসল VBA কোড
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
রূপান্তরিত অ্যাপস স্ক্রিপ্ট কোড (এক্সেপশন এরর যোগ করার আগে)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
এক্সেপশন এরর থ্রো করার জন্য অ্যাপস স্ক্রিপ্ট কোড যোগ করা হয়েছে।
/**
* 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));