مقاله فنی

ارجاعات ساختاریافته جدول اکسل در Delphi با HotXLS

HotXLS اکنون ارجاعات ساختاریافته جدول را ارزیابی می‌کند، پس =SUM(Table1[Amount]) یک عدد تولید می‌کند به‌جای اینکه رد شود. حل‌کننده Table[Column]، Table[[Column]]، بازه‌های ستون مثل Table[[Q1]:[Q4]]، و مشخص‌کننده‌های مورد [#Data]، [#All]، [#Headers] و [#Totals] را مدیریت می‌کند، و هرکدام را در برابر مدل جدول کتاب‌کار در زمان تجزیه حل می‌کند، در حالی که متن اصلی فرمول عیناً رفت‌وبرگشت می‌کند

یک فرم عمداً غایب است، و همان چیزی است که مردم اول با آن برخورد می‌کنند. اختصار ردیف جاری [@Column] پشتیبانی نمی‌شود، به یک دلیل ساختاری که ارزش فهمیدن دارد نه دور زدن کورکورانه

چرا یک ارجاع ساختاریافته صرفاً یک بازه با یک نام دوستانه نیست؟

چون یک نام تعریف‌شده یک آدرس را منجمد می‌کند و یک ارجاع جدول این کار را نمی‌کند. DataBlock را به‌عنوان یک نام که به Sheet1!$A$2:$D$100 اشاره می‌کند بنویسید و آن همان مستطیل باقی می‌ماند تا زمانی که چیزی آن را بازنویسی کند. Sales[Amount] را بنویسید و یعنی «ستون Amount از جدول Sales»، هرچه که وسعت آن جدول در لحظه ارزیابی فرمول باشد. بیست ردیف به جدول اضافه کنید و مجموع آن‌ها را پوشش می‌دهد؛ هیچ ارجاعی برای تنظیم‌کردن نیست چون از ابتدا هیچ آدرسی در فرمول وجود نداشت

همان کیفیت نمادین دقیقاً همان دلیلی است که ارجاع نمی‌تواند با جایگزینی رشته‌ای حل شود. حل‌کننده باید جدول را با نام در کتاب‌کار پیدا کند، ستون را با متن سرستون آن جست‌وجو کند، تصمیم بگیرد مشخص‌کننده مورد درخواستی کدام ردیف‌ها را پوشش می‌دهد، و یک مستطیل عینی تولید کند. HotXLS این کار را طی کامپایل فرمول از طریق مدل جدول انجام می‌دهد، به همین دلیل یک فرمول نوشته‌شده پیش از رشد جدول همچنان در برابر وسعت فعلی جدول ارزیابی می‌شود

گرامری که HotXLS حل می‌کند

گرامر پشتیبانی‌شده یک نتیجه مستطیلی واحد را پوشش می‌دهد و ارزش بیان دقیق دارد، چون مستندات اکسل سطحی بسیار بزرگ‌تر از آنچه بیشتر موتورها پیاده‌سازی می‌کنند ارائه می‌دهد. HotXLS [Col] و نوع داخل‌کروشه [[Col]]، مشخص‌کننده‌های مورد خام [#Data]، [#All]، [#Headers] و [#Totals]، فرم ترکیبی [[#Data],[Col]]، یک بازه درون یک مشخص‌کننده مورد به‌صورت [[#Data],[Col1]:[Col2]]، و یک بازه ساده [Col1]:[Col2] را می‌پذیرد

چیزی که آن مجموعه به شما می‌دهد هر شکل ارجاعی است که یک بلوک پیوسته تولید می‌کند: یک ستون، یک دنباله از ستون‌های مجاور، یک برش فقط-بدنه یا شامل-سرستون از هرکدام. اتحادهای غیرمجاور و نتایج چندناحیه‌ای بیرون از آن هستند. وقتی یک ارجاع قابل‌حل نیست، فرمول رفتار قبلی skip-without-value را حفظ می‌کند به‌جای جایگزین‌کردن یک حدس، پس یک ارجاع غیرقابل‌حل هرگز به یک عدد اشتباه باورپذیر تبدیل نمی‌شود

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Cols: TStringList;
begin
  Book := TXLSXWorkbook.Create;
  Cols := TStringList.Create;
  try
    Sheet := Book.Sheets.Add('Sales');
    Cols.Add('Region');
    Cols.Add('Q1');
    Cols.Add('Q2');
    Cols.Add('Amount');
    Sheet.Tables.Add('SalesTable', 'A1:D25', Cols);
    // ... نوشتن ردیف سرستون و 24 ردیف داده ...

    Sheet.Cells[27, 4].Formula := 'SUM(SalesTable[Amount])';
    Sheet.Cells[28, 4].Formula := 'SUM(SalesTable[[Q1]:[Q2]])';
    Sheet.Cells[29, 4].Formula := 'COUNTA(SalesTable[[#Data],[Region]])';
    Sheet.Cells[30, 4].Formula := 'ROWS(SalesTable[#All])';

    Book.Recalculate;
    Book.SaveAs('sales.xlsx');
  finally
    Cols.Free;
    Book.Free;
  end;
end;

چرا فرم ردیف جاری عمداً حذف شده؟

[@Column] و [#This Row] یعنی «سلول آن ستون روی ردیفی که این فرمول در آن زندگی می‌کند». بنابراین مقدار به موقعیت سلول ارزیابی‌کننده بستگی دارد، نه فقط به جدول. آن یک نوع متفاوت از ارجاع است: نه یک مستطیل که کامپایلر بتواند یک‌بار حل کند، بلکه یک حل‌کردن به‌ازای هر سلول که باید برای هر ردیفی که فرمول اشغال می‌کند دوباره انجام شود

HotXLS برای آن فرم‌ها از حل‌کننده بازه جدول False بازمی‌گرداند، که آن‌ها را به مسیر skip-without-value هدایت می‌کند. متن فرمول حفظ می‌شود و بدون تغییر پس‌نوشته می‌شود، پس یک کتاب‌کار که از [@Amount] استفاده می‌کند پس از یک رفت‌وبرگشت از برنامه شما به‌درستی در اکسل باز می‌شود؛ فقط مقدار محاسبه‌شده توسط HotXLS غایب است. با انتخاب بین یک مقدار غایب و یک مقدار محاسبه‌شده در برابر ردیف اشتباه، غیاب همان چیزی است که می‌توانید تشخیص دهید

دورزدن عملی مکانیکی است: در یک کتاب‌کاری که تولید می‌کنید، ارجاع نسبی معادل به سبک A1 را بنویسید، همان چیزی که اکسل به‌هرحال برای بخش زیادی از منطق با دامنه جدول به‌طور داخلی ذخیره می‌کند. در یک کتاب‌کاری که فقط پردازش می‌کنید، فرمول را دست‌نخورده بگذارید و مقدار کش‌شده‌ای که اکسل از پیش ذخیره کرده را بخوانید، همان چیزی که یک پایپ‌لاین بارگذاری-و-گزارش معمولاً می‌خواهد

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Table: TXLSXTable;
  Row: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.Open('sales.xlsx') <> 1 then Exit;
    Sheet := Book.Sheets[1];

    Table := Sheet.Tables.FindByName('SalesTable');
    if Table <> nil then
    begin
      // جست‌وجوی سبک Recordset روی بدنه جدول، نتیجه ردیف مبنای 1
      Row := Table.FindFirst(Sheet, 'Region', 'EMEA');
      while Row > 0 do
      begin
        Log(VarToStr(Sheet.Cells[Row, 4].Value));
        Row := Table.FindNext(Sheet, 'Region', 'EMEA', Row);
      end;
    end;
  finally
    Book.Free;
  end;
end;

وقتی شکل جدول تغییر می‌کند چه اتفاقی می‌افتد

ارجاعات ساختاریافته وقتی چیزی که نام‌گذاری می‌کنند از بین می‌رود، به‌جای بازاشاره‌دهی بی‌صدا، باطل می‌شوند. یک ستون را حذف کنید و فرمول‌هایی که به آن ستون ارجاع می‌دهند همان‌طور که اکسل باطلشان می‌کند باطل می‌شوند؛ جدول را حذف یا تغییرنام دهید و ارجاعات به آن به همان روش مدیریت می‌شوند. این رفتار درست است و تنظیم ارجاع معمولی توضیح داده‌شده در تنظیم ارجاع فرمول هنگام درج و حذف را بازتاب می‌دهد، جایی که کار موتور صادق‌نگه‌داشتن فرمول‌هاست نه معتبر-به‌نظر-رساندن آن‌ها

رشد ردیف مورد معکوس است و اصلاً نیازی به تنظیم ندارد. چون ارجاع جدول را نام‌گذاری می‌کند نه یک مستطیل را، ضمیمه‌کردن ردیف‌ها درون بازه جدول، آنچه [#Data] پوشش می‌دهد را بدون دست‌زدن به یک فرمول واحد گسترش می‌دهد. آن همان ویژگی‌ای است که جدول‌ها را ارزش استفاده در یک قالب گزارش می‌کند: ردیف جمع‌کل به جمع‌زدن هرچیزی که واردات تولید کرده ادامه می‌دهد، هرچقدر که آن ردیف‌ها بوده باشند

انضباط رفت‌وبرگشت

HotXLS متن فرمول اصلی را نگه می‌دارد. یک کتاب‌کار بارگذاری‌شده با SUM(SalesTable[Amount]) با همان SUM(SalesTable[Amount]) ذخیره می‌شود، نه با SUM(D2:D25) حل‌شده. این بیشتر از آنچه به نظر می‌رسد اهمیت دارد: کاربری که خروجی شما را در اکسل باز می‌کند انتظار دارد همان فرمولی را ببیند که نوشته، و یک آدرس حل‌شده به‌آرامی یک مدل خودنگهدار را به یک مدل شکننده تبدیل می‌کند که دیگر ردیف‌های جدید را پوشش نمی‌دهد

دو قابلیت مرتبط تصویر را کامل می‌کنند. تعریف‌های خود جدول، از جمله جدول‌های بدون‌سرستون و توضیحات به‌ازای هر جدول، از طریق مدل جدول توضیح داده‌شده در اعتبارسنجی داده، AutoFilter و جدول‌های اکسل رفت‌وبرگشت می‌کنند. و وقتی بسیاری از سلول‌ها یک الگو را به اشتراک می‌گذارند، XLSX آن‌ها را یک‌بار به‌عنوان یک فرمول مشترک ذخیره می‌کند، که مطابق گسترش si فرمول مشترک باز و دوباره صادر می‌شود. ارجاعات ساختاریافته درون فرمول‌های مشترک از هر دو مسیر عبور می‌کنند، پس هر دو باید درست رفتار کنند، و می‌کنند

HotXLS فایل‌های XLS، XLSX و ODS را از Delphi و C++Builder بدون نصب Excel و بدون هیچ اتوماسیون Office می‌خواند و می‌نویسد، و فرمول‌ها را در موتور خودش ارزیابی می‌کند. مدل جدول، موتور فرمول و API بازمحاسبه در صفحه کامپوننت صفحه‌گسترده Delphi HotXLS مستند شده‌اند