{
  "schemaVersion": "1.0",
  "item": {
    "slug": "afrexai-spreadsheet-engineering",
    "name": "Spreadsheet Engineering",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/1kalin/afrexai-spreadsheet-engineering",
    "canonicalUrl": "https://clawhub.ai/1kalin/afrexai-spreadsheet-engineering",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/afrexai-spreadsheet-engineering",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-spreadsheet-engineering",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/afrexai-spreadsheet-engineering"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/afrexai-spreadsheet-engineering",
    "agentPageUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering/agent",
    "manifestUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Spreadsheet Engineering — AfrexAI",
        "body": "Build bulletproof spreadsheets: financial models, dashboards, data systems, and automation. Platform-agnostic methodology for Google Sheets, Excel, and LibreOffice."
      },
      {
        "title": "Quick Health Check",
        "body": "Score your spreadsheet /16:\n\nSignalHealthySickNamed ranges for all key inputs✅ Uses named ranges❌ Raw cell references everywhereInputs separated from calculations✅ Clear input section❌ Hardcoded values in formulasNo circular references✅ Clean dependency chain❌ Iterative calculation warningsDocumentation/comments exist✅ README sheet + cell notes❌ \"What does this formula do?\"Error handling in formulas✅ IFERROR/IFNA wrapping❌ #REF! #N/A scattered everywhereConsistent formatting✅ Style guide followed❌ Random fonts, colors, sizesVersion history/backup✅ Named versions + changelog❌ \"Final_v3_REAL_final.xlsx\"Data validation on inputs✅ Dropdowns + range constraints❌ Free-text in structured fields\n\nScore: 0-4 🔴 rebuild | 5-8 🟡 refactor | 9-12 🟢 optimize | 13-16 🔵 production-grade"
      },
      {
        "title": "Spreadsheet Strategy Brief",
        "body": "spreadsheet_brief:\n  name: \"[Descriptive Name]\"\n  purpose: \"[What decision does this support?]\"\n  owner: \"[Who maintains this]\"\n  audience: \"[Who uses this — technical level]\"\n  update_frequency: \"[Real-time / Daily / Weekly / Monthly / Ad-hoc]\"\n  data_sources:\n    - source: \"[Where data comes from]\"\n      method: \"[Manual / Import / API / IMPORTRANGE / Power Query]\"\n      refresh: \"[How often]\"\n  outputs:\n    - \"[Dashboard / Report / Export / Decision support]\"\n  complexity_tier: \"[Simple / Standard / Complex / Enterprise]\"\n  platform: \"[Google Sheets / Excel / Both]\"\n  kill_criteria:\n    - \"If >50 users need simultaneous editing → move to database\"\n    - \"If >100K rows → move to database or BI tool\"\n    - \"If requires audit trail → move to proper system\""
      },
      {
        "title": "Complexity Tier Guide",
        "body": "TierRowsSheetsUsersFormulasExampleSimple<1K1-31-3BasicBudget tracker, checklistStandard1K-10K3-83-10IntermediateFinancial model, project trackerComplex10K-50K8-1510-30AdvancedMulti-dept dashboard, CRMEnterprise50K+15+30+ExpertData warehouse substitute (🚩 migrate)"
      },
      {
        "title": "When NOT to Use a Spreadsheet",
        "body": "ScenarioBetter Tool>100K rows of dataDatabase (PostgreSQL, SQLite)>10 concurrent editorsWeb app or AirtableComplex relational data (3+ entity types)Database + appNeeds audit trail / compliancePurpose-built systemReal-time data processingETL pipeline + BI toolVersion-controlled code logicActual code (Python, JS)\n\nRule: Spreadsheets are prototyping tools that become production systems by accident. Know when to graduate."
      },
      {
        "title": "Recommended Structure",
        "body": "📊 Workbook\n├── 📋 README          — Purpose, instructions, changelog\n├── 📊 Dashboard       — Charts, KPIs, summary (output only)\n├── ⚙️ Config          — Settings, parameters, dropdowns\n├── 📥 Data_Input      — Raw data entry or imports\n├── 🔧 Calculations    — All formulas and transformations\n├── 📈 Analysis        — Pivot tables, scenarios, what-if\n├── 📤 Output          — Formatted reports for export/print\n└── 🗄️ Reference       — Lookup tables, constants, mappings"
      },
      {
        "title": "7 Architecture Rules",
        "body": "One direction of flow — Data flows left→right or top→bottom. Never circular.\nInputs separate from calculations — NEVER hardcode numbers in formulas. Use named ranges.\nOne fact in one place — If a value is used in 3 places, define it once and reference it.\nColor code by purpose — Blue = input, Black = formula, Green = linked from other sheet, Red = warning.\nFreeze panes on every data sheet — Header row and label columns always visible.\nProtect formula cells — Lock everything except input cells. Prevent accidental overwrites.\nREADME sheet is mandatory — Every workbook starts with purpose, instructions, and changelog."
      },
      {
        "title": "Naming Conventions",
        "body": "Sheets:    PascalCase — Dashboard, Raw_Data, Config\nNamed Ranges: SCREAMING_SNAKE — TAX_RATE, START_DATE, REVENUE_TARGET\nTabs:      Prefix with emoji or number for sort order — 01_Dashboard, 02_Config\nFiles:     YYYY-MM-DD_Description_vX.xlsx"
      },
      {
        "title": "Color Coding Standard",
        "body": "ColorMeaningWhen to Use🔵 Light blue backgroundUser input cellEditable fields⬛ Black textFormula/calculatedAuto-populated cells🟢 Green textLinked from other sheetCross-sheet references🔴 Red text/backgroundWarning/errorValidation failures, negative values🟡 Yellow backgroundAssumptionKey assumptions that drive the model⬜ Grey backgroundReference/lockedConstants, lookup tables"
      },
      {
        "title": "Formula Complexity Levels",
        "body": "LevelTechniquesExampleL1 BasicSUM, AVERAGE, COUNT, IF, CONCATENATE=SUM(B2:B100)L2 IntermediateVLOOKUP/XLOOKUP, SUMIFS, INDEX/MATCH, TEXT=XLOOKUP(A2,Ref!A:A,Ref!B:B)L3 AdvancedARRAYFORMULA, QUERY, INDIRECT, nested IFs=QUERY(Data!A:F,\"SELECT A,SUM(F) GROUP BY A\")L4 ExpertLAMBDA, MAP/REDUCE, LET, dynamic arrays, MAKEARRAY=LET(data,A2:A100,filtered,FILTER(data,data>0),SORT(filtered))"
      },
      {
        "title": "Essential Formula Patterns",
        "body": "Lookup — Always Prefer XLOOKUP/INDEX-MATCH Over VLOOKUP\n\n❌ VLOOKUP (fragile — breaks when columns inserted):\n=VLOOKUP(A2, Data!A:D, 4, FALSE)\n\n✅ XLOOKUP (Excel 365 / Google Sheets):\n=XLOOKUP(A2, Data!A:A, Data!D:D, \"Not Found\")\n\n✅ INDEX/MATCH (universal — works everywhere):\n=INDEX(Data!D:D, MATCH(A2, Data!A:A, 0))\n\nMulti-Criteria Lookup\n\n=XLOOKUP(1, (Data!A:A=B2)*(Data!B:B=C2), Data!D:D, \"Not Found\")\n\nOr INDEX/MATCH array (Ctrl+Shift+Enter in older Excel):\n=INDEX(Data!D:D, MATCH(1, (Data!A:A=B2)*(Data!B:B=C2), 0))\n\nConditional Aggregation\n\nSingle condition:\n=SUMIF(Category, \"Sales\", Amount)\n\nMultiple conditions:\n=SUMIFS(Amount, Category, \"Sales\", Region, \"US\", Date, \">=\"&DATE(2025,1,1))\n\nCount with conditions:\n=COUNTIFS(Status, \"Active\", Score, \">80\")\n\nAverage with conditions:\n=AVERAGEIFS(Score, Department, \"Engineering\", Status, \"Active\")\n\nDate Calculations\n\nWorking days between dates:\n=NETWORKDAYS(Start, End, Holidays)\n\nAdd working days:\n=WORKDAY(Start, 10, Holidays)\n\nMonth-end date:\n=EOMONTH(A2, 0)\n\nQuarter from date:\n=ROUNDUP(MONTH(A2)/3, 0)\n\nFiscal year (Apr-Mar):\n=IF(MONTH(A2)>=4, YEAR(A2), YEAR(A2)-1)\n\nText Manipulation\n\nExtract domain from email:\n=MID(A2, FIND(\"@\",A2)+1, LEN(A2))\n\nProper case with exceptions:\n=PROPER(SUBSTITUTE(LOWER(A2),\" llc\",\" LLC\"))\n\nClean messy data:\n=TRIM(CLEAN(SUBSTITUTE(A2, CHAR(160), \" \")))\n\nDynamic Arrays (Excel 365 / Google Sheets)\n\nFILTER:\n=FILTER(Data, Data[Status]=\"Active\", Data[Amount]>1000)\n\nSORT:\n=SORT(FILTER(Data, Data[Region]=\"US\"), 3, -1)\n\nUNIQUE:\n=UNIQUE(Data[Category])\n\nSEQUENCE:\n=SEQUENCE(12, 1, DATE(2025,1,1), 30)  — 12 monthly dates\n\nGoogle Sheets QUERY (Power Feature)\n\nBasic aggregation:\n=QUERY(Data!A:F, \"SELECT A, SUM(F) WHERE B='Active' GROUP BY A ORDER BY SUM(F) DESC LABEL SUM(F) 'Total Revenue'\")\n\nDate filtering:\n=QUERY(Data!A:F, \"SELECT A, B, F WHERE C >= date '\"&TEXT(B1,\"yyyy-MM-dd\")&\"' ORDER BY F DESC LIMIT 10\")\n\nPivot-style:\n=QUERY(Data!A:F, \"SELECT A, SUM(F) GROUP BY A PIVOT B\")\n\nLET for Readable Complex Formulas\n\n=LET(\n  revenue, SUMIFS(Sales!D:D, Sales!A:A, A2),\n  costs, SUMIFS(Costs!D:D, Costs!A:A, A2),\n  margin, (revenue - costs) / revenue,\n  IF(revenue=0, \"No Data\",\n    IF(margin > 0.3, \"✅ Healthy\",\n      IF(margin > 0.1, \"⚠️ Watch\", \"🔴 Critical\")))\n)\n\nLAMBDA (Custom Functions)\n\nNamed LAMBDA (define in Name Manager / named ranges):\nFISCAL_QUARTER = LAMBDA(date, \"FY\"&IF(MONTH(date)>=4,YEAR(date),YEAR(date)-1)&\" Q\"&ROUNDUP(MOD(MONTH(date)+8,12)/3,0))\n\nMAP with LAMBDA:\n=MAP(A2:A100, LAMBDA(x, PROPER(TRIM(x))))"
      },
      {
        "title": "10 Formula Rules",
        "body": "NEVER hardcode values — Use named ranges or a Config sheet\nWrap external lookups in IFERROR — =IFERROR(XLOOKUP(...), \"Not Found\")\nUse LET for formulas >100 chars — Readable, debuggable, faster\nPrefer XLOOKUP over VLOOKUP — More flexible, no column counting\nOne formula per cell — Don't nest 5+ functions. Break into helper columns.\nComment complex formulas — Use cell notes or a documentation column\nTest with edge cases — Empty cells, zeros, dates before 1900, text in number fields\nAvoid INDIRECT for performance — It's volatile (recalculates every time)\nUse structured references in tables — =SUM(Table1[Amount]) not =SUM(D:D)\nKeep formulas auditable — Someone else (or future you) must understand them"
      },
      {
        "title": "Input Validation Checklist",
        "body": "Data TypeValidationImplementationDateDate rangeData validation: between START and ENDCurrencyNumber ≥ 0Data validation: decimal ≥ 0, format $#,##0.00Percentage0-100 or 0-1Data validation: decimal between 0 and 1CategoryDropdown listData validation: list from Reference sheetEmailContains @Custom: =ISNUMBER(FIND(\"@\",A2))PhoneLength checkCustom: =AND(LEN(A2)>=10, LEN(A2)<=15)Required fieldNot blankCustom: =LEN(TRIM(A2))>0ID/CodeUnique + formatCustom: =AND(COUNTIF(A:A,A2)=1, LEN(A2)=8)"
      },
      {
        "title": "Data Cleaning Pipeline",
        "body": "Step 1: Remove whitespace\n=TRIM(CLEAN(A2))\n\nStep 2: Standardize case\n=PROPER(A2) or =UPPER(A2)\n\nStep 3: Remove duplicates\nUse Remove Duplicates tool or UNIQUE()\n\nStep 4: Fix dates\n=DATEVALUE(TEXT(A2,\"YYYY-MM-DD\"))\n\nStep 5: Validate\n=IF(AND(A2>0, A2<1000000, ISNUMBER(A2)), \"✅\", \"❌ Check\")"
      },
      {
        "title": "Conditional Formatting Rules (Priority Order)",
        "body": "🔴 Errors — Any cell with #REF!, #N/A, #VALUE! → Red background\n🟡 Warnings — Values outside expected range → Yellow background\n🟢 Positive — On-target metrics → Green text\n📊 Data bars — Numeric ranges → Proportional bars\n🎯 Icons — Status indicators → Traffic light icon sets"
      },
      {
        "title": "Model Architecture",
        "body": "📊 Financial Model\n├── 📋 Cover          — Model name, version, date, author\n├── ⚙️ Assumptions    — ALL inputs here (blue cells), scenarios\n├── 📊 Revenue        — Revenue build-up by product/segment\n├── 📊 COGS           — Cost of goods/services\n├── 📊 OpEx           — Operating expenses by category\n├── 📊 P&L            — Income statement (auto-calculated)\n├── 📊 Balance_Sheet  — Assets, liabilities, equity\n├── 📊 Cash_Flow      — Operating, investing, financing\n├── 📈 DCF            — Discounted cash flow valuation\n├── 📈 Scenarios      — Bull/Base/Bear cases\n├── 📊 KPIs           — Key metrics dashboard\n└── 📊 Charts         — Visualizations"
      },
      {
        "title": "Revenue Model Patterns",
        "body": "saas_revenue:\n  mrr_start: \"=PREVIOUS_MONTH_MRR\"\n  new_mrr: \"=NEW_CUSTOMERS * ARPU\"\n  expansion_mrr: \"=EXISTING * EXPANSION_RATE / 12\"\n  contraction_mrr: \"=EXISTING * CONTRACTION_RATE / 12\"\n  churn_mrr: \"=EXISTING * CHURN_RATE / 12\"\n  mrr_end: \"=MRR_START + NEW + EXPANSION - CONTRACTION - CHURN\"\n  arr: \"=MRR_END * 12\"\n\nunit_economics:\n  cac: \"=TOTAL_SALES_MARKETING / NEW_CUSTOMERS\"\n  ltv: \"=ARPU / MONTHLY_CHURN_RATE\"\n  ltv_cac_ratio: \"=LTV / CAC  # Target: >3.0\"\n  cac_payback_months: \"=CAC / ARPU  # Target: <12\""
      },
      {
        "title": "Scenario Analysis Template",
        "body": "=SWITCH(SCENARIO_SELECTOR,\n  \"Bull\", Assumptions!B2 * 1.3,\n  \"Base\", Assumptions!B2,\n  \"Bear\", Assumptions!B2 * 0.7,\n  Assumptions!B2)\n\nOr with CHOOSE:\n=CHOOSE(SCENARIO_INDEX, BEAR_VALUE, BASE_VALUE, BULL_VALUE)"
      },
      {
        "title": "Sensitivity Analysis (Data Table)",
        "body": "Two-variable data table:\n- Row input: Growth Rate (10%, 15%, 20%, 25%, 30%)\n- Column input: Churn Rate (2%, 3%, 5%, 7%, 10%)\n- Output cell: NPV or IRR\n- Select range → Data → What-If Analysis → Data Table"
      },
      {
        "title": "Common Financial Formulas",
        "body": "NPV: =NPV(DISCOUNT_RATE, CF1:CF10) + INITIAL_INVESTMENT\nIRR: =IRR(CF_RANGE, guess)\nXIRR: =XIRR(CF_VALUES, CF_DATES)  — irregular cash flows\nPMT: =PMT(RATE/12, NPER*12, -PV)  — loan payment\nCompound growth: =FV * (1 + RATE)^YEARS\nCAGR: =(END_VALUE/START_VALUE)^(1/YEARS) - 1\nBreak-even units: =FIXED_COSTS / (PRICE - VARIABLE_COST)"
      },
      {
        "title": "Dashboard Layout",
        "body": "┌─────────────────────────────────────────────────┐\n│  📊 Dashboard Title              Period: [Dropdown] │\n│  Last Updated: [Auto]            Filter: [Dropdown] │\n├──────────┬──────────┬──────────┬──────────────────┤\n│  KPI 1   │  KPI 2   │  KPI 3   │  KPI 4           │\n│  $1.2M   │  45%     │  128     │  $47             │\n│  ▲ 12%   │  ▼ -3%   │  ▲ 8%   │  ● Flat          │\n├──────────┴──────────┴──────────┴──────────────────┤\n│                                                     │\n│  [Primary Chart — Revenue Trend]                   │\n│                                                     │\n├─────────────────────┬───────────────────────────────┤\n│  [Secondary Chart]  │  [Table / Top Items]          │\n│  [Category Split]   │  [Ranked List]                │\n└─────────────────────┴───────────────────────────────┘"
      },
      {
        "title": "KPI Card Formula Pattern",
        "body": "Current value:  =SUMIFS(Data!E:E, Data!A:A, \">=\"&PERIOD_START, Data!A:A, \"<=\"&PERIOD_END)\nPrevious value: =SUMIFS(Data!E:E, Data!A:A, \">=\"&PREV_START, Data!A:A, \"<=\"&PREV_END)\nChange %:       =(CURRENT - PREVIOUS) / ABS(PREVIOUS)\nIndicator:      =IF(CHANGE>0.05, \"▲\", IF(CHANGE<-0.05, \"▼\", \"●\"))\nDisplay:        =INDICATOR & \" \" & TEXT(ABS(CHANGE), \"0.0%\")"
      },
      {
        "title": "Chart Selection Guide",
        "body": "Data PatternBest ChartAvoidTrend over timeLine chartPie chartPart of wholeStacked bar or donut3D pieComparisonHorizontal barRadar chartDistributionHistogramLine chartRelationshipScatter plotBar chartKPI vs targetBullet chart or gaugeComplex chartGeographicHeat map or filled mapBar chart"
      },
      {
        "title": "7 Chart Rules",
        "body": "Title = Insight, not description. \"Revenue grew 23% in Q3\" not \"Q3 Revenue Chart\"\nStart Y-axis at zero for bar charts. Line charts can truncate with clear labeling.\nMax 5-7 data series per chart. Use \"Other\" category for the rest.\nRemove chartjunk — No 3D effects, gradient fills, excessive gridlines.\nUse consistent colors — Same category = same color across all charts.\nLabel directly on chart where possible. Minimize legend lookups.\nSort meaningfully — By value (largest→smallest) or chronologically. Never alphabetically unless it's the only logical order."
      },
      {
        "title": "Interactive Dashboard Controls",
        "body": "Filter by dropdown:\n1. Config sheet: Data validation dropdown for Region, Period, Category\n2. Dashboard formulas use dropdown value:\n   =SUMIFS(Data!E:E, Data!C:C, CONFIG_REGION, Data!A:A, \">=\"&CONFIG_START)\n\nSparklines (in-cell mini charts):\n=SPARKLINE(B2:M2, {\"charttype\",\"line\"; \"color\",\"#2563eb\"; \"linewidth\",2})"
      },
      {
        "title": "Import Method Selection",
        "body": "SourceMethodRefreshCSV/Excel fileManual import / Power QueryManualGoogle Sheets (other)IMPORTRANGEAuto (varies)Web page tableIMPORTHTML / Power QueryAuto / manualAPI / JSONIMPORTDATA / Apps Script / Power QueryScheduledDatabasePower Query / ODBCScheduledAnother sheet (same workbook)Direct referenceReal-time"
      },
      {
        "title": "Google Sheets Import Functions",
        "body": "From another spreadsheet:\n=IMPORTRANGE(\"spreadsheet_url\", \"Sheet1!A1:D100\")\n\nFrom web page (table):\n=IMPORTHTML(\"url\", \"table\", 1)\n\nFrom CSV:\n=IMPORTDATA(\"csv_url\")\n\nFrom XML/RSS:\n=IMPORTXML(\"url\", \"//item/title\")"
      },
      {
        "title": "Excel Power Query Patterns",
        "body": "1. Data → Get Data → From [Source]\n2. Transform in Power Query Editor\n3. Close & Load (to table or connection only)\n\nEssential transforms:\n- Remove columns → Right-click header → Remove\n- Filter rows → Click filter arrow\n- Split column → Transform → Split Column\n- Unpivot → Select ID columns → Unpivot Other Columns\n- Merge queries → Home → Merge (= VLOOKUP but better)\n- Append queries → Home → Append (= UNION)"
      },
      {
        "title": "IMPORTRANGE Best Practices",
        "body": "Rules:\n1. Authorize on first use (one-time popup)\n2. Use named ranges in source spreadsheet\n3. Wrap in IFERROR for graceful failures\n4. Minimize imported range — don't import entire sheets\n5. Cache results if auto-refresh causes slowness\n\nPattern:\n=IFERROR(\n  IMPORTRANGE(SOURCE_URL, \"Data!A1:D\"&SOURCE_ROW_COUNT),\n  \"⚠️ Connection failed — check source spreadsheet access\"\n)"
      },
      {
        "title": "Google Apps Script Essentials",
        "body": "// Auto-populate timestamp on edit\nfunction onEdit(e) {\n  const sheet = e.source.getActiveSheet();\n  if (sheet.getName() === \"Data\" && e.range.getColumn() >= 2) {\n    sheet.getRange(e.range.getRow(), 1).setValue(new Date());\n  }\n}\n\n// Email report on schedule (set up trigger)\nfunction sendWeeklyReport() {\n  const ss = SpreadsheetApp.getActiveSpreadsheet();\n  const dashboard = ss.getSheetByName(\"Dashboard\");\n  const kpi1 = dashboard.getRange(\"B2\").getDisplayValue();\n  const kpi2 = dashboard.getRange(\"C2\").getDisplayValue();\n  \n  MailApp.sendEmail({\n    to: \"team@company.com\",\n    subject: `Weekly Report — ${Utilities.formatDate(new Date(), \"GMT\", \"MMM dd\")}`,\n    htmlBody: `<h2>Weekly KPIs</h2><p>Revenue: ${kpi1}</p><p>Growth: ${kpi2}</p>`\n  });\n}\n\n// Auto-archive rows older than 90 days\nfunction archiveOldRows() {\n  const ss = SpreadsheetApp.getActiveSpreadsheet();\n  const data = ss.getSheetByName(\"Data\");\n  const archive = ss.getSheetByName(\"Archive\");\n  const cutoff = new Date();\n  cutoff.setDate(cutoff.getDate() - 90);\n  \n  const rows = data.getDataRange().getValues();\n  for (let i = rows.length - 1; i >= 1; i--) {\n    if (rows[i][0] < cutoff) {\n      archive.appendRow(rows[i]);\n      data.deleteRow(i + 1);\n    }\n  }\n}"
      },
      {
        "title": "Excel VBA Essentials",
        "body": "' Auto-format new entries\nPrivate Sub Worksheet_Change(ByVal Target As Range)\n    If Not Intersect(Target, Range(\"A:A\")) Is Nothing Then\n        Application.EnableEvents = False\n        Target.Offset(0, 5).Value = Now\n        Application.EnableEvents = True\n    End If\nEnd Sub\n\n' Refresh all Power Query connections\nSub RefreshAllData()\n    ThisWorkbook.RefreshAll\n    MsgBox \"All data refreshed at \" & Now\nEnd Sub"
      },
      {
        "title": "Automation Decision Guide",
        "body": "TaskGoogle SheetsExcelOn-edit timestampApps Script onEditVBA Worksheet_ChangeScheduled emailApps Script + triggerPower AutomateData refreshApps Script + triggerPower Query + schedulePDF exportApps ScriptVBA + SaveAsCross-system syncApps Script + APIPower Automate / VBACustom functionsApps Script CUSTOM_FUNCTIONVBA UDF or LAMBDA"
      },
      {
        "title": "Performance Killers (Ranked)",
        "body": "IssueImpactFixINDIRECT/OFFSET (volatile)🔴 CriticalReplace with INDEX/XLOOKUPWhole-column references (A:A)🔴 CriticalUse bounded ranges (A2:A1000)ARRAYFORMULA on huge ranges🟡 HighLimit range or use QUERYExcessive conditional formatting🟡 HighReduce rules, use bounded rangesToo many IMPORTRANGE🟡 HighConsolidate, cache locallyUnused sheets with formulas🟢 MediumDelete or clear unused sheetsComplex nested IFs🟢 MediumReplace with SWITCH/IFS/XLOOKUPHeavy formatting (images, shapes)🟢 MediumMinimize decorative elements"
      },
      {
        "title": "Google Sheets Performance Rules",
        "body": "Keep workbook under 5M cells (ideal: <500K)\nLimit IMPORTRANGE to <10 per workbook\nUse QUERY instead of multiple SUMIFS when possible\nPut ARRAYFORMULA results on a dedicated calc sheet\nAvoid NOW()/TODAY() in frequently-recalculated areas"
      },
      {
        "title": "Excel Performance Rules",
        "body": "Use tables (Ctrl+T) for structured data — better performance than raw ranges\nPower Query > formulas for data transformation\nXLOOKUP > VLOOKUP > INDEX/MATCH for speed\nTurn off auto-calculation during bulk edits: Application.Calculation = xlManual\nUse Power Pivot for >100K rows instead of formulas"
      },
      {
        "title": "Access Control Strategy",
        "body": "RolePermissionsImplementationOwnerFull controlOriginal creatorEditorEdit data, not structureShare with edit, protect structure sheetsAnalystEdit inputs, view outputsProtect all except input cellsViewerView onlyShare as viewerCommenterView + commentShare as commenter"
      },
      {
        "title": "Sheet Protection Pattern",
        "body": "1. Protect entire workbook structure (prevent sheet add/delete/rename)\n2. Protect each sheet\n3. UNLOCK only input cells (blue-coded)\n4. Set password for admin overrides\n5. Document which cells are editable in README"
      },
      {
        "title": "Version Control",
        "body": "Naming: YYYY-MM-DD_ModelName_vX.Y\n  X = major change (new section, restructure)\n  Y = minor change (formula fix, data update)\n\nChangelog (on README sheet):\n| Date | Version | Author | Change |\n|------|---------|--------|--------|\n| 2025-03-15 | 2.1 | Jane | Added Q2 actuals |\n| 2025-03-01 | 2.0 | John | Restructured revenue model |"
      },
      {
        "title": "Collaboration Rules",
        "body": "Never edit someone else's model without telling them\nUse named versions before major changes (Google Sheets: File → Version history → Name current version)\nComment on cells — don't explain in chat, explain in the sheet\nOne editor at a time for complex formula areas — use \"editing\" flag cell\nWeekly review — Check for broken references, stale data, unused sheets"
      },
      {
        "title": "Budget Tracker Template",
        "body": "Columns: Month | Category | Subcategory | Budgeted | Actual | Variance | % Variance\nKPIs: Total Budget | Total Spent | Remaining | Burn Rate | Projected Year-End\nCharts: Budget vs Actual (bar), Spend by Category (donut), Monthly Trend (line)\nFormulas:\n  Variance: =Actual - Budgeted\n  % Variance: =IF(Budgeted=0, \"\", (Actual-Budgeted)/ABS(Budgeted))\n  Burn Rate: =SUMIFS(Actual, Month, \"<=\"&TODAY()) / (MONTH(TODAY()) * Total_Budget / 12)"
      },
      {
        "title": "Project Tracker Template",
        "body": "Columns: Task | Owner | Status | Priority | Start | Due | Days Left | % Complete | Notes\nStatus: 🔴 Blocked | 🟡 In Progress | 🟢 Complete | ⚪ Not Started\nFormulas:\n  Days Left: =IF(Status=\"🟢 Complete\", \"✅\", MAX(0, Due-TODAY()))\n  Overdue flag: =IF(AND(Status<>\"🟢 Complete\", Due<TODAY()), \"⚠️ OVERDUE\", \"\")\n  Completion %: =COUNTIF(Status, \"🟢 Complete\") / COUNTA(Status)\nDashboard: Gantt-style with conditional formatting date bars"
      },
      {
        "title": "Sales Pipeline Template",
        "body": "Columns: Deal | Company | Stage | Amount | Probability | Weighted | Owner | Close Date | Days in Stage | Next Action\nStages: Prospect (10%) | Qualified (25%) | Proposal (50%) | Negotiation (75%) | Closed Won (100%) | Lost (0%)\nFormulas:\n  Weighted: =Amount * Probability\n  Pipeline: =SUMIFS(Weighted, Stage, \"<>\"&\"Lost\", Stage, \"<>\"&\"Closed Won\")\n  Velocity: =AVERAGE(Days_to_Close_for_Won_Deals)\nDashboard: Pipeline by stage (funnel), Forecast vs quota, Win rate trend"
      },
      {
        "title": "OKR Tracker Template",
        "body": "Columns: Objective | Key Result | Metric | Start | Current | Target | Score | Status\nScore: =MIN(1, (Current - Start) / (Target - Start))\nStatus: =IF(Score>=0.7, \"🟢\", IF(Score>=0.4, \"🟡\", \"🔴\"))\nOverall: =AVERAGE(Score) across all KRs per Objective"
      },
      {
        "title": "Spreadsheet Quality Rubric (0-100)",
        "body": "DimensionWeightScoringArchitecture15%Clear sheet structure, data flow direction, READMEFormula Quality20%Named ranges, error handling, no hardcodingData Validation15%Input constraints, dropdowns, type checkingVisual Design10%Consistent formatting, color coding, readabilityDocumentation15%Cell notes, README, changelog, instructionsPerformance10%No volatile functions, bounded ranges, fast recalcError Handling10%IFERROR wrappers, validation checks, no broken refsMaintainability5%Protected structure, clear ownership, versioned"
      },
      {
        "title": "Monthly Maintenance Checklist",
        "body": "Check for #REF! and #N/A errors across all sheets\n Verify data source connections are refreshing\n Review and update assumptions (Config sheet)\n Remove unused sheets and named ranges\n Check file size — if growing, archive old data\n Test all dropdowns and validation rules\n Update README with any changes made\n Create named version snapshot"
      },
      {
        "title": "10 Spreadsheet Killers",
        "body": "MistakeImpactFixHardcoded numbers in formulasCan't audit or updateNamed ranges + Config sheetNo error handling#N/A cascades break everythingIFERROR on all lookupsWhole-column referencesSlow, crashes on large dataBounded rangesCircular referencesUnpredictable resultsRedesign calculation flowNo documentation\"What does this formula do?\"README + cell notesNo data validationGarbage in = garbage outDropdowns + constraintsOne mega-sheetUnmaintainable, slowSplit by functionNo backup/versionsOne mistake = lost workNamed versions + exportsCopy-paste instead of formulasStale data, inconsistenciesUse references/IMPORTRANGEManual processes that should be automatedError-prone, time-wastingScripts or scheduled refreshes"
      },
      {
        "title": "Migrating Excel ↔ Google Sheets",
        "body": "XLOOKUP works in both (Excel 365 + Google Sheets)\nQUERY is Google Sheets only — replace with Power Query in Excel\nARRAYFORMULA is Google Sheets — Excel uses Ctrl+Shift+Enter or dynamic arrays\nApps Script → no Excel equivalent. Use VBA or Power Automate.\nPower Query / Power Pivot → no Google Sheets equivalent. Use QUERY or BigQuery connector.\nTest all formulas after migration. Named ranges may break."
      },
      {
        "title": "Multi-Currency Spreadsheets",
        "body": "=Amount * XLOOKUP(Currency, FX_Rates!A:A, FX_Rates!B:B)\nOr with GOOGLEFINANCE:\n=Amount * GOOGLEFINANCE(\"CURRENCY:GBPUSD\")"
      },
      {
        "title": "Large Dataset Workarounds (>100K rows)",
        "body": "Split data across multiple sheets by time period\nUse pivot tables / QUERY instead of row-level formulas\nImport summarized data, not raw transactions\nConsider BigQuery + Connected Sheets (Google) or Power Pivot (Excel)\nIf you need >500K rows, graduate to a database"
      },
      {
        "title": "Natural Language Commands",
        "body": "When working with spreadsheets, you can ask:\n\n\"Audit this spreadsheet for quality issues\"\n\"Design a financial model for [business type]\"\n\"Create a dashboard layout for [metrics]\"\n\"Write the formulas for [calculation]\"\n\"Optimize this spreadsheet for performance\"\n\"Build a data validation system for [input type]\"\n\"Create an Apps Script to [automate task]\"\n\"Design a template for [use case]\"\n\"Review this formula and suggest improvements\"\n\"Help me migrate this from Excel to Google Sheets\"\n\"Set up a scenario analysis for [model]\"\n\"Build a KPI tracker for [department]\""
      },
      {
        "title": "⚡ Level Up — AfrexAI Context Packs",
        "body": "This skill covers spreadsheet engineering methodology. For industry-specific financial models, dashboards, and templates:\n\n💰 SaaS Context Pack — MRR/ARR models, SaaS metrics dashboards, cohort analysis templates\n🏦 Fintech Context Pack — Financial modeling, risk calculators, compliance trackers\n🏭 Manufacturing Context Pack — Production trackers, inventory models, cost analysis\n🏗️ Construction Context Pack — Project budgets, bid calculators, resource planning\n\n$47 per pack — Complete AI agent context for your industry.\n\nBrowse all packs: AfrexAI Storefront →"
      },
      {
        "title": "🔗 More Free Skills by AfrexAI",
        "body": "afrexai-data-storytelling — Data visualization & dashboard design methodology\nafrexai-personal-finance — Complete personal finance operating system\nafrexai-product-analytics — Product metrics & analytics engineering\nafrexai-fpa-engine — Financial planning & analysis\nafrexai-automation-strategy — Workflow automation methodology\n\nBuilt by AfrexAI — AI agents that compound capital and code."
      }
    ],
    "body": "Spreadsheet Engineering — AfrexAI\n\nBuild bulletproof spreadsheets: financial models, dashboards, data systems, and automation. Platform-agnostic methodology for Google Sheets, Excel, and LibreOffice.\n\nQuick Health Check\n\nScore your spreadsheet /16:\n\nSignal\tHealthy\tSick\nNamed ranges for all key inputs\t✅ Uses named ranges\t❌ Raw cell references everywhere\nInputs separated from calculations\t✅ Clear input section\t❌ Hardcoded values in formulas\nNo circular references\t✅ Clean dependency chain\t❌ Iterative calculation warnings\nDocumentation/comments exist\t✅ README sheet + cell notes\t❌ \"What does this formula do?\"\nError handling in formulas\t✅ IFERROR/IFNA wrapping\t❌ #REF! #N/A scattered everywhere\nConsistent formatting\t✅ Style guide followed\t❌ Random fonts, colors, sizes\nVersion history/backup\t✅ Named versions + changelog\t❌ \"Final_v3_REAL_final.xlsx\"\nData validation on inputs\t✅ Dropdowns + range constraints\t❌ Free-text in structured fields\n\nScore: 0-4 🔴 rebuild | 5-8 🟡 refactor | 9-12 🟢 optimize | 13-16 🔵 production-grade\n\nPhase 1: Architecture & Planning\nSpreadsheet Strategy Brief\nspreadsheet_brief:\n  name: \"[Descriptive Name]\"\n  purpose: \"[What decision does this support?]\"\n  owner: \"[Who maintains this]\"\n  audience: \"[Who uses this — technical level]\"\n  update_frequency: \"[Real-time / Daily / Weekly / Monthly / Ad-hoc]\"\n  data_sources:\n    - source: \"[Where data comes from]\"\n      method: \"[Manual / Import / API / IMPORTRANGE / Power Query]\"\n      refresh: \"[How often]\"\n  outputs:\n    - \"[Dashboard / Report / Export / Decision support]\"\n  complexity_tier: \"[Simple / Standard / Complex / Enterprise]\"\n  platform: \"[Google Sheets / Excel / Both]\"\n  kill_criteria:\n    - \"If >50 users need simultaneous editing → move to database\"\n    - \"If >100K rows → move to database or BI tool\"\n    - \"If requires audit trail → move to proper system\"\n\nComplexity Tier Guide\nTier\tRows\tSheets\tUsers\tFormulas\tExample\nSimple\t<1K\t1-3\t1-3\tBasic\tBudget tracker, checklist\nStandard\t1K-10K\t3-8\t3-10\tIntermediate\tFinancial model, project tracker\nComplex\t10K-50K\t8-15\t10-30\tAdvanced\tMulti-dept dashboard, CRM\nEnterprise\t50K+\t15+\t30+\tExpert\tData warehouse substitute (🚩 migrate)\nWhen NOT to Use a Spreadsheet\nScenario\tBetter Tool\n>100K rows of data\tDatabase (PostgreSQL, SQLite)\n>10 concurrent editors\tWeb app or Airtable\nComplex relational data (3+ entity types)\tDatabase + app\nNeeds audit trail / compliance\tPurpose-built system\nReal-time data processing\tETL pipeline + BI tool\nVersion-controlled code logic\tActual code (Python, JS)\n\nRule: Spreadsheets are prototyping tools that become production systems by accident. Know when to graduate.\n\nPhase 2: Sheet Architecture\nRecommended Structure\n📊 Workbook\n├── 📋 README          — Purpose, instructions, changelog\n├── 📊 Dashboard       — Charts, KPIs, summary (output only)\n├── ⚙️ Config          — Settings, parameters, dropdowns\n├── 📥 Data_Input      — Raw data entry or imports\n├── 🔧 Calculations    — All formulas and transformations\n├── 📈 Analysis        — Pivot tables, scenarios, what-if\n├── 📤 Output          — Formatted reports for export/print\n└── 🗄️ Reference       — Lookup tables, constants, mappings\n\n7 Architecture Rules\nOne direction of flow — Data flows left→right or top→bottom. Never circular.\nInputs separate from calculations — NEVER hardcode numbers in formulas. Use named ranges.\nOne fact in one place — If a value is used in 3 places, define it once and reference it.\nColor code by purpose — Blue = input, Black = formula, Green = linked from other sheet, Red = warning.\nFreeze panes on every data sheet — Header row and label columns always visible.\nProtect formula cells — Lock everything except input cells. Prevent accidental overwrites.\nREADME sheet is mandatory — Every workbook starts with purpose, instructions, and changelog.\nNaming Conventions\nSheets:    PascalCase — Dashboard, Raw_Data, Config\nNamed Ranges: SCREAMING_SNAKE — TAX_RATE, START_DATE, REVENUE_TARGET\nTabs:      Prefix with emoji or number for sort order — 01_Dashboard, 02_Config\nFiles:     YYYY-MM-DD_Description_vX.xlsx\n\nColor Coding Standard\nColor\tMeaning\tWhen to Use\n🔵 Light blue background\tUser input cell\tEditable fields\n⬛ Black text\tFormula/calculated\tAuto-populated cells\n🟢 Green text\tLinked from other sheet\tCross-sheet references\n🔴 Red text/background\tWarning/error\tValidation failures, negative values\n🟡 Yellow background\tAssumption\tKey assumptions that drive the model\n⬜ Grey background\tReference/locked\tConstants, lookup tables\nPhase 3: Formula Engineering\nFormula Complexity Levels\nLevel\tTechniques\tExample\nL1 Basic\tSUM, AVERAGE, COUNT, IF, CONCATENATE\t=SUM(B2:B100)\nL2 Intermediate\tVLOOKUP/XLOOKUP, SUMIFS, INDEX/MATCH, TEXT\t=XLOOKUP(A2,Ref!A:A,Ref!B:B)\nL3 Advanced\tARRAYFORMULA, QUERY, INDIRECT, nested IFs\t=QUERY(Data!A:F,\"SELECT A,SUM(F) GROUP BY A\")\nL4 Expert\tLAMBDA, MAP/REDUCE, LET, dynamic arrays, MAKEARRAY\t=LET(data,A2:A100,filtered,FILTER(data,data>0),SORT(filtered))\nEssential Formula Patterns\nLookup — Always Prefer XLOOKUP/INDEX-MATCH Over VLOOKUP\n❌ VLOOKUP (fragile — breaks when columns inserted):\n=VLOOKUP(A2, Data!A:D, 4, FALSE)\n\n✅ XLOOKUP (Excel 365 / Google Sheets):\n=XLOOKUP(A2, Data!A:A, Data!D:D, \"Not Found\")\n\n✅ INDEX/MATCH (universal — works everywhere):\n=INDEX(Data!D:D, MATCH(A2, Data!A:A, 0))\n\nMulti-Criteria Lookup\n=XLOOKUP(1, (Data!A:A=B2)*(Data!B:B=C2), Data!D:D, \"Not Found\")\n\nOr INDEX/MATCH array (Ctrl+Shift+Enter in older Excel):\n=INDEX(Data!D:D, MATCH(1, (Data!A:A=B2)*(Data!B:B=C2), 0))\n\nConditional Aggregation\nSingle condition:\n=SUMIF(Category, \"Sales\", Amount)\n\nMultiple conditions:\n=SUMIFS(Amount, Category, \"Sales\", Region, \"US\", Date, \">=\"&DATE(2025,1,1))\n\nCount with conditions:\n=COUNTIFS(Status, \"Active\", Score, \">80\")\n\nAverage with conditions:\n=AVERAGEIFS(Score, Department, \"Engineering\", Status, \"Active\")\n\nDate Calculations\nWorking days between dates:\n=NETWORKDAYS(Start, End, Holidays)\n\nAdd working days:\n=WORKDAY(Start, 10, Holidays)\n\nMonth-end date:\n=EOMONTH(A2, 0)\n\nQuarter from date:\n=ROUNDUP(MONTH(A2)/3, 0)\n\nFiscal year (Apr-Mar):\n=IF(MONTH(A2)>=4, YEAR(A2), YEAR(A2)-1)\n\nText Manipulation\nExtract domain from email:\n=MID(A2, FIND(\"@\",A2)+1, LEN(A2))\n\nProper case with exceptions:\n=PROPER(SUBSTITUTE(LOWER(A2),\" llc\",\" LLC\"))\n\nClean messy data:\n=TRIM(CLEAN(SUBSTITUTE(A2, CHAR(160), \" \")))\n\nDynamic Arrays (Excel 365 / Google Sheets)\nFILTER:\n=FILTER(Data, Data[Status]=\"Active\", Data[Amount]>1000)\n\nSORT:\n=SORT(FILTER(Data, Data[Region]=\"US\"), 3, -1)\n\nUNIQUE:\n=UNIQUE(Data[Category])\n\nSEQUENCE:\n=SEQUENCE(12, 1, DATE(2025,1,1), 30)  — 12 monthly dates\n\nGoogle Sheets QUERY (Power Feature)\nBasic aggregation:\n=QUERY(Data!A:F, \"SELECT A, SUM(F) WHERE B='Active' GROUP BY A ORDER BY SUM(F) DESC LABEL SUM(F) 'Total Revenue'\")\n\nDate filtering:\n=QUERY(Data!A:F, \"SELECT A, B, F WHERE C >= date '\"&TEXT(B1,\"yyyy-MM-dd\")&\"' ORDER BY F DESC LIMIT 10\")\n\nPivot-style:\n=QUERY(Data!A:F, \"SELECT A, SUM(F) GROUP BY A PIVOT B\")\n\nLET for Readable Complex Formulas\n=LET(\n  revenue, SUMIFS(Sales!D:D, Sales!A:A, A2),\n  costs, SUMIFS(Costs!D:D, Costs!A:A, A2),\n  margin, (revenue - costs) / revenue,\n  IF(revenue=0, \"No Data\",\n    IF(margin > 0.3, \"✅ Healthy\",\n      IF(margin > 0.1, \"⚠️ Watch\", \"🔴 Critical\")))\n)\n\nLAMBDA (Custom Functions)\nNamed LAMBDA (define in Name Manager / named ranges):\nFISCAL_QUARTER = LAMBDA(date, \"FY\"&IF(MONTH(date)>=4,YEAR(date),YEAR(date)-1)&\" Q\"&ROUNDUP(MOD(MONTH(date)+8,12)/3,0))\n\nMAP with LAMBDA:\n=MAP(A2:A100, LAMBDA(x, PROPER(TRIM(x))))\n\n10 Formula Rules\nNEVER hardcode values — Use named ranges or a Config sheet\nWrap external lookups in IFERROR — =IFERROR(XLOOKUP(...), \"Not Found\")\nUse LET for formulas >100 chars — Readable, debuggable, faster\nPrefer XLOOKUP over VLOOKUP — More flexible, no column counting\nOne formula per cell — Don't nest 5+ functions. Break into helper columns.\nComment complex formulas — Use cell notes or a documentation column\nTest with edge cases — Empty cells, zeros, dates before 1900, text in number fields\nAvoid INDIRECT for performance — It's volatile (recalculates every time)\nUse structured references in tables — =SUM(Table1[Amount]) not =SUM(D:D)\nKeep formulas auditable — Someone else (or future you) must understand them\nPhase 4: Data Validation & Quality\nInput Validation Checklist\nData Type\tValidation\tImplementation\nDate\tDate range\tData validation: between START and END\nCurrency\tNumber ≥ 0\tData validation: decimal ≥ 0, format $#,##0.00\nPercentage\t0-100 or 0-1\tData validation: decimal between 0 and 1\nCategory\tDropdown list\tData validation: list from Reference sheet\nEmail\tContains @\tCustom: =ISNUMBER(FIND(\"@\",A2))\nPhone\tLength check\tCustom: =AND(LEN(A2)>=10, LEN(A2)<=15)\nRequired field\tNot blank\tCustom: =LEN(TRIM(A2))>0\nID/Code\tUnique + format\tCustom: =AND(COUNTIF(A:A,A2)=1, LEN(A2)=8)\nData Cleaning Pipeline\nStep 1: Remove whitespace\n=TRIM(CLEAN(A2))\n\nStep 2: Standardize case\n=PROPER(A2) or =UPPER(A2)\n\nStep 3: Remove duplicates\nUse Remove Duplicates tool or UNIQUE()\n\nStep 4: Fix dates\n=DATEVALUE(TEXT(A2,\"YYYY-MM-DD\"))\n\nStep 5: Validate\n=IF(AND(A2>0, A2<1000000, ISNUMBER(A2)), \"✅\", \"❌ Check\")\n\nConditional Formatting Rules (Priority Order)\n🔴 Errors — Any cell with #REF!, #N/A, #VALUE! → Red background\n🟡 Warnings — Values outside expected range → Yellow background\n🟢 Positive — On-target metrics → Green text\n📊 Data bars — Numeric ranges → Proportional bars\n🎯 Icons — Status indicators → Traffic light icon sets\nPhase 5: Financial Modeling\nModel Architecture\n📊 Financial Model\n├── 📋 Cover          — Model name, version, date, author\n├── ⚙️ Assumptions    — ALL inputs here (blue cells), scenarios\n├── 📊 Revenue        — Revenue build-up by product/segment\n├── 📊 COGS           — Cost of goods/services\n├── 📊 OpEx           — Operating expenses by category\n├── 📊 P&L            — Income statement (auto-calculated)\n├── 📊 Balance_Sheet  — Assets, liabilities, equity\n├── 📊 Cash_Flow      — Operating, investing, financing\n├── 📈 DCF            — Discounted cash flow valuation\n├── 📈 Scenarios      — Bull/Base/Bear cases\n├── 📊 KPIs           — Key metrics dashboard\n└── 📊 Charts         — Visualizations\n\nRevenue Model Patterns\nsaas_revenue:\n  mrr_start: \"=PREVIOUS_MONTH_MRR\"\n  new_mrr: \"=NEW_CUSTOMERS * ARPU\"\n  expansion_mrr: \"=EXISTING * EXPANSION_RATE / 12\"\n  contraction_mrr: \"=EXISTING * CONTRACTION_RATE / 12\"\n  churn_mrr: \"=EXISTING * CHURN_RATE / 12\"\n  mrr_end: \"=MRR_START + NEW + EXPANSION - CONTRACTION - CHURN\"\n  arr: \"=MRR_END * 12\"\n\nunit_economics:\n  cac: \"=TOTAL_SALES_MARKETING / NEW_CUSTOMERS\"\n  ltv: \"=ARPU / MONTHLY_CHURN_RATE\"\n  ltv_cac_ratio: \"=LTV / CAC  # Target: >3.0\"\n  cac_payback_months: \"=CAC / ARPU  # Target: <12\"\n\nScenario Analysis Template\n=SWITCH(SCENARIO_SELECTOR,\n  \"Bull\", Assumptions!B2 * 1.3,\n  \"Base\", Assumptions!B2,\n  \"Bear\", Assumptions!B2 * 0.7,\n  Assumptions!B2)\n\nOr with CHOOSE:\n=CHOOSE(SCENARIO_INDEX, BEAR_VALUE, BASE_VALUE, BULL_VALUE)\n\nSensitivity Analysis (Data Table)\nTwo-variable data table:\n- Row input: Growth Rate (10%, 15%, 20%, 25%, 30%)\n- Column input: Churn Rate (2%, 3%, 5%, 7%, 10%)\n- Output cell: NPV or IRR\n- Select range → Data → What-If Analysis → Data Table\n\nCommon Financial Formulas\nNPV: =NPV(DISCOUNT_RATE, CF1:CF10) + INITIAL_INVESTMENT\nIRR: =IRR(CF_RANGE, guess)\nXIRR: =XIRR(CF_VALUES, CF_DATES)  — irregular cash flows\nPMT: =PMT(RATE/12, NPER*12, -PV)  — loan payment\nCompound growth: =FV * (1 + RATE)^YEARS\nCAGR: =(END_VALUE/START_VALUE)^(1/YEARS) - 1\nBreak-even units: =FIXED_COSTS / (PRICE - VARIABLE_COST)\n\nPhase 6: Dashboard Design\nDashboard Layout\n┌─────────────────────────────────────────────────┐\n│  📊 Dashboard Title              Period: [Dropdown] │\n│  Last Updated: [Auto]            Filter: [Dropdown] │\n├──────────┬──────────┬──────────┬──────────────────┤\n│  KPI 1   │  KPI 2   │  KPI 3   │  KPI 4           │\n│  $1.2M   │  45%     │  128     │  $47             │\n│  ▲ 12%   │  ▼ -3%   │  ▲ 8%   │  ● Flat          │\n├──────────┴──────────┴──────────┴──────────────────┤\n│                                                     │\n│  [Primary Chart — Revenue Trend]                   │\n│                                                     │\n├─────────────────────┬───────────────────────────────┤\n│  [Secondary Chart]  │  [Table / Top Items]          │\n│  [Category Split]   │  [Ranked List]                │\n└─────────────────────┴───────────────────────────────┘\n\nKPI Card Formula Pattern\nCurrent value:  =SUMIFS(Data!E:E, Data!A:A, \">=\"&PERIOD_START, Data!A:A, \"<=\"&PERIOD_END)\nPrevious value: =SUMIFS(Data!E:E, Data!A:A, \">=\"&PREV_START, Data!A:A, \"<=\"&PREV_END)\nChange %:       =(CURRENT - PREVIOUS) / ABS(PREVIOUS)\nIndicator:      =IF(CHANGE>0.05, \"▲\", IF(CHANGE<-0.05, \"▼\", \"●\"))\nDisplay:        =INDICATOR & \" \" & TEXT(ABS(CHANGE), \"0.0%\")\n\nChart Selection Guide\nData Pattern\tBest Chart\tAvoid\nTrend over time\tLine chart\tPie chart\nPart of whole\tStacked bar or donut\t3D pie\nComparison\tHorizontal bar\tRadar chart\nDistribution\tHistogram\tLine chart\nRelationship\tScatter plot\tBar chart\nKPI vs target\tBullet chart or gauge\tComplex chart\nGeographic\tHeat map or filled map\tBar chart\n7 Chart Rules\nTitle = Insight, not description. \"Revenue grew 23% in Q3\" not \"Q3 Revenue Chart\"\nStart Y-axis at zero for bar charts. Line charts can truncate with clear labeling.\nMax 5-7 data series per chart. Use \"Other\" category for the rest.\nRemove chartjunk — No 3D effects, gradient fills, excessive gridlines.\nUse consistent colors — Same category = same color across all charts.\nLabel directly on chart where possible. Minimize legend lookups.\nSort meaningfully — By value (largest→smallest) or chronologically. Never alphabetically unless it's the only logical order.\nInteractive Dashboard Controls\nFilter by dropdown:\n1. Config sheet: Data validation dropdown for Region, Period, Category\n2. Dashboard formulas use dropdown value:\n   =SUMIFS(Data!E:E, Data!C:C, CONFIG_REGION, Data!A:A, \">=\"&CONFIG_START)\n\nSparklines (in-cell mini charts):\n=SPARKLINE(B2:M2, {\"charttype\",\"line\"; \"color\",\"#2563eb\"; \"linewidth\",2})\n\nPhase 7: Data Import & Integration\nImport Method Selection\nSource\tMethod\tRefresh\nCSV/Excel file\tManual import / Power Query\tManual\nGoogle Sheets (other)\tIMPORTRANGE\tAuto (varies)\nWeb page table\tIMPORTHTML / Power Query\tAuto / manual\nAPI / JSON\tIMPORTDATA / Apps Script / Power Query\tScheduled\nDatabase\tPower Query / ODBC\tScheduled\nAnother sheet (same workbook)\tDirect reference\tReal-time\nGoogle Sheets Import Functions\nFrom another spreadsheet:\n=IMPORTRANGE(\"spreadsheet_url\", \"Sheet1!A1:D100\")\n\nFrom web page (table):\n=IMPORTHTML(\"url\", \"table\", 1)\n\nFrom CSV:\n=IMPORTDATA(\"csv_url\")\n\nFrom XML/RSS:\n=IMPORTXML(\"url\", \"//item/title\")\n\nExcel Power Query Patterns\n1. Data → Get Data → From [Source]\n2. Transform in Power Query Editor\n3. Close & Load (to table or connection only)\n\nEssential transforms:\n- Remove columns → Right-click header → Remove\n- Filter rows → Click filter arrow\n- Split column → Transform → Split Column\n- Unpivot → Select ID columns → Unpivot Other Columns\n- Merge queries → Home → Merge (= VLOOKUP but better)\n- Append queries → Home → Append (= UNION)\n\nIMPORTRANGE Best Practices\nRules:\n1. Authorize on first use (one-time popup)\n2. Use named ranges in source spreadsheet\n3. Wrap in IFERROR for graceful failures\n4. Minimize imported range — don't import entire sheets\n5. Cache results if auto-refresh causes slowness\n\nPattern:\n=IFERROR(\n  IMPORTRANGE(SOURCE_URL, \"Data!A1:D\"&SOURCE_ROW_COUNT),\n  \"⚠️ Connection failed — check source spreadsheet access\"\n)\n\nPhase 8: Automation & Scripts\nGoogle Apps Script Essentials\n// Auto-populate timestamp on edit\nfunction onEdit(e) {\n  const sheet = e.source.getActiveSheet();\n  if (sheet.getName() === \"Data\" && e.range.getColumn() >= 2) {\n    sheet.getRange(e.range.getRow(), 1).setValue(new Date());\n  }\n}\n\n// Email report on schedule (set up trigger)\nfunction sendWeeklyReport() {\n  const ss = SpreadsheetApp.getActiveSpreadsheet();\n  const dashboard = ss.getSheetByName(\"Dashboard\");\n  const kpi1 = dashboard.getRange(\"B2\").getDisplayValue();\n  const kpi2 = dashboard.getRange(\"C2\").getDisplayValue();\n  \n  MailApp.sendEmail({\n    to: \"team@company.com\",\n    subject: `Weekly Report — ${Utilities.formatDate(new Date(), \"GMT\", \"MMM dd\")}`,\n    htmlBody: `<h2>Weekly KPIs</h2><p>Revenue: ${kpi1}</p><p>Growth: ${kpi2}</p>`\n  });\n}\n\n// Auto-archive rows older than 90 days\nfunction archiveOldRows() {\n  const ss = SpreadsheetApp.getActiveSpreadsheet();\n  const data = ss.getSheetByName(\"Data\");\n  const archive = ss.getSheetByName(\"Archive\");\n  const cutoff = new Date();\n  cutoff.setDate(cutoff.getDate() - 90);\n  \n  const rows = data.getDataRange().getValues();\n  for (let i = rows.length - 1; i >= 1; i--) {\n    if (rows[i][0] < cutoff) {\n      archive.appendRow(rows[i]);\n      data.deleteRow(i + 1);\n    }\n  }\n}\n\nExcel VBA Essentials\n' Auto-format new entries\nPrivate Sub Worksheet_Change(ByVal Target As Range)\n    If Not Intersect(Target, Range(\"A:A\")) Is Nothing Then\n        Application.EnableEvents = False\n        Target.Offset(0, 5).Value = Now\n        Application.EnableEvents = True\n    End If\nEnd Sub\n\n' Refresh all Power Query connections\nSub RefreshAllData()\n    ThisWorkbook.RefreshAll\n    MsgBox \"All data refreshed at \" & Now\nEnd Sub\n\nAutomation Decision Guide\nTask\tGoogle Sheets\tExcel\nOn-edit timestamp\tApps Script onEdit\tVBA Worksheet_Change\nScheduled email\tApps Script + trigger\tPower Automate\nData refresh\tApps Script + trigger\tPower Query + schedule\nPDF export\tApps Script\tVBA + SaveAs\nCross-system sync\tApps Script + API\tPower Automate / VBA\nCustom functions\tApps Script CUSTOM_FUNCTION\tVBA UDF or LAMBDA\nPhase 9: Performance Optimization\nPerformance Killers (Ranked)\nIssue\tImpact\tFix\nINDIRECT/OFFSET (volatile)\t🔴 Critical\tReplace with INDEX/XLOOKUP\nWhole-column references (A:A)\t🔴 Critical\tUse bounded ranges (A2:A1000)\nARRAYFORMULA on huge ranges\t🟡 High\tLimit range or use QUERY\nExcessive conditional formatting\t🟡 High\tReduce rules, use bounded ranges\nToo many IMPORTRANGE\t🟡 High\tConsolidate, cache locally\nUnused sheets with formulas\t🟢 Medium\tDelete or clear unused sheets\nComplex nested IFs\t🟢 Medium\tReplace with SWITCH/IFS/XLOOKUP\nHeavy formatting (images, shapes)\t🟢 Medium\tMinimize decorative elements\nGoogle Sheets Performance Rules\nKeep workbook under 5M cells (ideal: <500K)\nLimit IMPORTRANGE to <10 per workbook\nUse QUERY instead of multiple SUMIFS when possible\nPut ARRAYFORMULA results on a dedicated calc sheet\nAvoid NOW()/TODAY() in frequently-recalculated areas\nExcel Performance Rules\nUse tables (Ctrl+T) for structured data — better performance than raw ranges\nPower Query > formulas for data transformation\nXLOOKUP > VLOOKUP > INDEX/MATCH for speed\nTurn off auto-calculation during bulk edits: Application.Calculation = xlManual\nUse Power Pivot for >100K rows instead of formulas\nPhase 10: Collaboration & Governance\nAccess Control Strategy\nRole\tPermissions\tImplementation\nOwner\tFull control\tOriginal creator\nEditor\tEdit data, not structure\tShare with edit, protect structure sheets\nAnalyst\tEdit inputs, view outputs\tProtect all except input cells\nViewer\tView only\tShare as viewer\nCommenter\tView + comment\tShare as commenter\nSheet Protection Pattern\n1. Protect entire workbook structure (prevent sheet add/delete/rename)\n2. Protect each sheet\n3. UNLOCK only input cells (blue-coded)\n4. Set password for admin overrides\n5. Document which cells are editable in README\n\nVersion Control\nNaming: YYYY-MM-DD_ModelName_vX.Y\n  X = major change (new section, restructure)\n  Y = minor change (formula fix, data update)\n\nChangelog (on README sheet):\n| Date | Version | Author | Change |\n|------|---------|--------|--------|\n| 2025-03-15 | 2.1 | Jane | Added Q2 actuals |\n| 2025-03-01 | 2.0 | John | Restructured revenue model |\n\nCollaboration Rules\nNever edit someone else's model without telling them\nUse named versions before major changes (Google Sheets: File → Version history → Name current version)\nComment on cells — don't explain in chat, explain in the sheet\nOne editor at a time for complex formula areas — use \"editing\" flag cell\nWeekly review — Check for broken references, stale data, unused sheets\nPhase 11: Common Templates\nBudget Tracker Template\nColumns: Month | Category | Subcategory | Budgeted | Actual | Variance | % Variance\nKPIs: Total Budget | Total Spent | Remaining | Burn Rate | Projected Year-End\nCharts: Budget vs Actual (bar), Spend by Category (donut), Monthly Trend (line)\nFormulas:\n  Variance: =Actual - Budgeted\n  % Variance: =IF(Budgeted=0, \"\", (Actual-Budgeted)/ABS(Budgeted))\n  Burn Rate: =SUMIFS(Actual, Month, \"<=\"&TODAY()) / (MONTH(TODAY()) * Total_Budget / 12)\n\nProject Tracker Template\nColumns: Task | Owner | Status | Priority | Start | Due | Days Left | % Complete | Notes\nStatus: 🔴 Blocked | 🟡 In Progress | 🟢 Complete | ⚪ Not Started\nFormulas:\n  Days Left: =IF(Status=\"🟢 Complete\", \"✅\", MAX(0, Due-TODAY()))\n  Overdue flag: =IF(AND(Status<>\"🟢 Complete\", Due<TODAY()), \"⚠️ OVERDUE\", \"\")\n  Completion %: =COUNTIF(Status, \"🟢 Complete\") / COUNTA(Status)\nDashboard: Gantt-style with conditional formatting date bars\n\nSales Pipeline Template\nColumns: Deal | Company | Stage | Amount | Probability | Weighted | Owner | Close Date | Days in Stage | Next Action\nStages: Prospect (10%) | Qualified (25%) | Proposal (50%) | Negotiation (75%) | Closed Won (100%) | Lost (0%)\nFormulas:\n  Weighted: =Amount * Probability\n  Pipeline: =SUMIFS(Weighted, Stage, \"<>\"&\"Lost\", Stage, \"<>\"&\"Closed Won\")\n  Velocity: =AVERAGE(Days_to_Close_for_Won_Deals)\nDashboard: Pipeline by stage (funnel), Forecast vs quota, Win rate trend\n\nOKR Tracker Template\nColumns: Objective | Key Result | Metric | Start | Current | Target | Score | Status\nScore: =MIN(1, (Current - Start) / (Target - Start))\nStatus: =IF(Score>=0.7, \"🟢\", IF(Score>=0.4, \"🟡\", \"🔴\"))\nOverall: =AVERAGE(Score) across all KRs per Objective\n\nPhase 12: Quality & Maintenance\nSpreadsheet Quality Rubric (0-100)\nDimension\tWeight\tScoring\nArchitecture\t15%\tClear sheet structure, data flow direction, README\nFormula Quality\t20%\tNamed ranges, error handling, no hardcoding\nData Validation\t15%\tInput constraints, dropdowns, type checking\nVisual Design\t10%\tConsistent formatting, color coding, readability\nDocumentation\t15%\tCell notes, README, changelog, instructions\nPerformance\t10%\tNo volatile functions, bounded ranges, fast recalc\nError Handling\t10%\tIFERROR wrappers, validation checks, no broken refs\nMaintainability\t5%\tProtected structure, clear ownership, versioned\nMonthly Maintenance Checklist\n Check for #REF! and #N/A errors across all sheets\n Verify data source connections are refreshing\n Review and update assumptions (Config sheet)\n Remove unused sheets and named ranges\n Check file size — if growing, archive old data\n Test all dropdowns and validation rules\n Update README with any changes made\n Create named version snapshot\n10 Spreadsheet Killers\nMistake\tImpact\tFix\nHardcoded numbers in formulas\tCan't audit or update\tNamed ranges + Config sheet\nNo error handling\t#N/A cascades break everything\tIFERROR on all lookups\nWhole-column references\tSlow, crashes on large data\tBounded ranges\nCircular references\tUnpredictable results\tRedesign calculation flow\nNo documentation\t\"What does this formula do?\"\tREADME + cell notes\nNo data validation\tGarbage in = garbage out\tDropdowns + constraints\nOne mega-sheet\tUnmaintainable, slow\tSplit by function\nNo backup/versions\tOne mistake = lost work\tNamed versions + exports\nCopy-paste instead of formulas\tStale data, inconsistencies\tUse references/IMPORTRANGE\nManual processes that should be automated\tError-prone, time-wasting\tScripts or scheduled refreshes\nEdge Cases\nMigrating Excel ↔ Google Sheets\nXLOOKUP works in both (Excel 365 + Google Sheets)\nQUERY is Google Sheets only — replace with Power Query in Excel\nARRAYFORMULA is Google Sheets — Excel uses Ctrl+Shift+Enter or dynamic arrays\nApps Script → no Excel equivalent. Use VBA or Power Automate.\nPower Query / Power Pivot → no Google Sheets equivalent. Use QUERY or BigQuery connector.\nTest all formulas after migration. Named ranges may break.\nMulti-Currency Spreadsheets\n=Amount * XLOOKUP(Currency, FX_Rates!A:A, FX_Rates!B:B)\nOr with GOOGLEFINANCE:\n=Amount * GOOGLEFINANCE(\"CURRENCY:GBPUSD\")\n\nLarge Dataset Workarounds (>100K rows)\nSplit data across multiple sheets by time period\nUse pivot tables / QUERY instead of row-level formulas\nImport summarized data, not raw transactions\nConsider BigQuery + Connected Sheets (Google) or Power Pivot (Excel)\nIf you need >500K rows, graduate to a database\nNatural Language Commands\n\nWhen working with spreadsheets, you can ask:\n\n\"Audit this spreadsheet for quality issues\"\n\"Design a financial model for [business type]\"\n\"Create a dashboard layout for [metrics]\"\n\"Write the formulas for [calculation]\"\n\"Optimize this spreadsheet for performance\"\n\"Build a data validation system for [input type]\"\n\"Create an Apps Script to [automate task]\"\n\"Design a template for [use case]\"\n\"Review this formula and suggest improvements\"\n\"Help me migrate this from Excel to Google Sheets\"\n\"Set up a scenario analysis for [model]\"\n\"Build a KPI tracker for [department]\"\n⚡ Level Up — AfrexAI Context Packs\n\nThis skill covers spreadsheet engineering methodology. For industry-specific financial models, dashboards, and templates:\n\n💰 SaaS Context Pack — MRR/ARR models, SaaS metrics dashboards, cohort analysis templates\n🏦 Fintech Context Pack — Financial modeling, risk calculators, compliance trackers\n🏭 Manufacturing Context Pack — Production trackers, inventory models, cost analysis\n🏗️ Construction Context Pack — Project budgets, bid calculators, resource planning\n\n$47 per pack — Complete AI agent context for your industry.\n\nBrowse all packs: AfrexAI Storefront →\n\n🔗 More Free Skills by AfrexAI\nafrexai-data-storytelling — Data visualization & dashboard design methodology\nafrexai-personal-finance — Complete personal finance operating system\nafrexai-product-analytics — Product metrics & analytics engineering\nafrexai-fpa-engine — Financial planning & analysis\nafrexai-automation-strategy — Workflow automation methodology\n\nBuilt by AfrexAI — AI agents that compound capital and code."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/1kalin/afrexai-spreadsheet-engineering",
    "publisherUrl": "https://clawhub.ai/1kalin/afrexai-spreadsheet-engineering",
    "owner": "1kalin",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering",
    "downloadUrl": "https://openagent3.xyz/downloads/afrexai-spreadsheet-engineering",
    "agentUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering/agent",
    "manifestUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/afrexai-spreadsheet-engineering/agent.md"
  }
}