excel.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/LevelEdit/excel.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 1/17/02 1:43p $*
  29. * *
  30. * $Revision:: 4 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. ///#include <comutil.h>
  37. #include "excel.h"
  38. #include <stdio.h>
  39. #include <assert.h>
  40. #include <comutil.h>
  41. #include <comdef.h>
  42. #include <afxdisp.h>
  43. #include "excel8.h"
  44. #include "utils.h"
  45. typedef enum {
  46. xlAll = -4104,
  47. xlAutomatic = -4105,
  48. xlBoth = 1,
  49. xlCenter = -4108,
  50. xlChecker = 9,
  51. xlCircle = 8,
  52. xlCorner = 2,
  53. xlCrissCross = 16,
  54. xlCross = 4,
  55. xlDiamond = 2,
  56. xlDistributed = -4117,
  57. xlDoubleAccounting = 5,
  58. xlFixedValue = 1,
  59. xlFormats = -4122,
  60. xlGray16 = 17,
  61. xlGray8 = 18,
  62. xlGrid = 15,
  63. xlHigh = -4127,
  64. xlInside = 2,
  65. xlJustify = -4130,
  66. xlLightDown = 13,
  67. xlLightHorizontal = 11,
  68. xlLightUp = 14,
  69. xlLightVertical = 12,
  70. xlLow = -4134,
  71. xlManual = -4135,
  72. xlMinusValues = 3,
  73. xlModule = -4141,
  74. xlNextToAxis = 4,
  75. xlNone = -4142,
  76. xlNotes = -4144,
  77. xlOff = -4146,
  78. xlOn = 1,
  79. xlPercent = 2,
  80. xlPlus = 9,
  81. xlPlusValues = 2,
  82. xlSemiGray75 = 10,
  83. xlShowLabel = 4,
  84. xlShowLabelAndPercent = 5,
  85. xlShowPercent = 3,
  86. xlShowValue = 2,
  87. xlSimple = -4154,
  88. xlSingle = 2,
  89. xlSingleAccounting = 4,
  90. xlSolid = 1,
  91. xlSquare = 1,
  92. xlStar = 5,
  93. xlStError = 4,
  94. xlToolbarButton = 2,
  95. xlTriangle = 3,
  96. xlGray25 = -4124,
  97. xlGray50 = -4125,
  98. xlGray75 = -4126,
  99. xlBottom = -4107,
  100. xlLeft = -4131,
  101. xlRight = -4152,
  102. xlTop = -4160,
  103. xl3DBar = -4099,
  104. xl3DSurface = -4103,
  105. xlBar = 2,
  106. xlColumn = 3,
  107. xlCombination = -4111,
  108. xlCustom = -4114,
  109. xlDefaultAutoFormat = -1,
  110. xlMaximum = 2,
  111. xlMinimum = 4,
  112. xlOpaque = 3,
  113. xlTransparent = 2,
  114. xlBidi = -5000,
  115. xlLatin = -5001,
  116. xlContext = -5002,
  117. xlLTR = -5003,
  118. xlRTL = -5004,
  119. xlVisualCursor = 2,
  120. xlLogicalCursor = 1,
  121. xlSystem = 1,
  122. xlPartial = 3,
  123. xlHindiNumerals = 3,
  124. xlBidiCalendar = 3,
  125. xlGregorian = 2,
  126. xlComplete = 4,
  127. xlScale = 3,
  128. xlClosed = 3,
  129. xlColor1 = 7,
  130. xlColor2 = 8,
  131. xlColor3 = 9,
  132. xlConstants = 2,
  133. xlContents = 2,
  134. xlBelow = 1,
  135. xlCascade = 7,
  136. xlCenterAcrossSelection = 7,
  137. xlChart4 = 2,
  138. xlChartSeries = 17,
  139. xlChartShort = 6,
  140. xlChartTitles = 18,
  141. xlClassic1 = 1,
  142. xlClassic2 = 2,
  143. xlClassic3 = 3,
  144. xl3DEffects1 = 13,
  145. xl3DEffects2 = 14,
  146. xlAbove = 0,
  147. xlAccounting1 = 4,
  148. xlAccounting2 = 5,
  149. xlAccounting3 = 6,
  150. xlAccounting4 = 17,
  151. xlAdd = 2,
  152. xlDebugCodePane = 13,
  153. xlDesktop = 9,
  154. xlDirect = 1,
  155. xlDivide = 5,
  156. xlDoubleClosed = 5,
  157. xlDoubleOpen = 4,
  158. xlDoubleQuote = 1,
  159. xlEntireChart = 20,
  160. xlExcelMenus = 1,
  161. xlExtended = 3,
  162. xlFill = 5,
  163. xlFirst = 0,
  164. xlFloating = 5,
  165. xlFormula = 5,
  166. xlGeneral = 1,
  167. xlGridline = 22,
  168. xlIcons = 1,
  169. xlImmediatePane = 12,
  170. xlInteger = 2,
  171. xlLast = 1,
  172. xlLastCell = 11,
  173. xlList1 = 10,
  174. xlList2 = 11,
  175. xlList3 = 12,
  176. xlLocalFormat1 = 15,
  177. xlLocalFormat2 = 16,
  178. xlLong = 3,
  179. xlLotusHelp = 2,
  180. xlMacrosheetCell = 7,
  181. xlMixed = 2,
  182. xlMultiply = 4,
  183. xlNarrow = 1,
  184. xlNoDocuments = 3,
  185. xlOpen = 2,
  186. xlOutside = 3,
  187. xlReference = 4,
  188. xlSemiautomatic = 2,
  189. xlShort = 1,
  190. xlSingleQuote = 2,
  191. xlStrict = 2,
  192. xlSubtract = 3,
  193. xlTextBox = 16,
  194. xlTiled = 1,
  195. xlTitleBar = 8,
  196. xlToolbar = 1,
  197. xlVisible = 12,
  198. xlWatchPane = 11,
  199. xlWide = 3,
  200. xlWorkbookTab = 6,
  201. xlWorksheet4 = 1,
  202. xlWorksheetCell = 3,
  203. xlWorksheetShort = 5,
  204. xlAllExceptBorders = 6,
  205. xlLeftToRight = 2,
  206. xlTopToBottom = 1,
  207. xlVeryHidden = 2,
  208. xlDrawingObject = 14
  209. } Constants;
  210. typedef enum {
  211. xlHairline = 1,
  212. xlMedium = -4138,
  213. xlThick = 4,
  214. xlThin = 2
  215. } XlBorderWeight;
  216. typedef enum {
  217. xlContinuous = 1,
  218. xlDash = -4115,
  219. xlDashDot = 4,
  220. xlDashDotDot = 5,
  221. xlDot = -4118,
  222. xlDouble = -4119,
  223. xlSlantDashDot = 13,
  224. xlLineStyleNone = -4142
  225. } XlLineStyle;
  226. typedef enum {
  227. xlInsideHorizontal = 12,
  228. xlInsideVertical = 11,
  229. xlDiagonalDown = 5,
  230. xlDiagonalUp = 6,
  231. xlEdgeBottom = 9,
  232. xlEdgeLeft = 7,
  233. xlEdgeRight = 10,
  234. xlEdgeTop = 8
  235. } XlBordersIndex;
  236. static const int xlWorkbookNormal = -4143;
  237. static const int xlNoChange = 1;
  238. static const int xlLocalSessionChanges = 2;
  239. static const int xlWBATWorksheet = -4167;
  240. static VARIANT no, yes, dummy, dummy0, nullstring, empty;
  241. static VARIANT continuous, automatic, medium, thin, none;
  242. static VARIANT yellow, solid;
  243. /////////////////////////////////////////////////////////////////////////
  244. // Static member initialization
  245. /////////////////////////////////////////////////////////////////////////
  246. _Application * ExcelClass::Application = NULL;
  247. Workbooks * ExcelClass::WorkbooksObj = NULL;
  248. _Worksheet * ExcelClass::WorksheetObj = NULL;
  249. _Workbook * ExcelClass::WorkbookObj = NULL;
  250. Range * ExcelClass::RangeObj = NULL;
  251. StringClass ExcelClass::CurrPath;
  252. /////////////////////////////////////////////////////////////////////////
  253. //
  254. // Initialize
  255. //
  256. /////////////////////////////////////////////////////////////////////////
  257. bool
  258. ExcelClass::Initialize (void)
  259. {
  260. //
  261. // Don't reinitialize
  262. //
  263. if (Application != NULL) {
  264. return true;
  265. }
  266. bool retval = false;
  267. //
  268. // Allocate the application object
  269. //
  270. Application = new _Application;
  271. //
  272. // Attempt to start excel
  273. //
  274. if (Application->CreateDispatch ("Excel.Application")) {
  275. //
  276. // Get the workbook interface
  277. //
  278. LPDISPATCH dispatch = Application->GetWorkbooks ();
  279. if (dispatch != NULL) {
  280. retval = true;
  281. //
  282. // Create the neccessary interfaces
  283. //
  284. WorkbooksObj = new Workbooks (dispatch);
  285. WorksheetObj = new _Worksheet;
  286. RangeObj = new Range;
  287. //
  288. // Dunno
  289. //
  290. V_VT ( &no ) = VT_BOOL;
  291. V_VT ( &yes ) = VT_BOOL;
  292. V_VT ( &dummy ) = VT_I4;
  293. V_VT ( &dummy0 ) = VT_I4;
  294. V_VT ( &nullstring ) = VT_BSTR ;
  295. V_VT ( &empty ) = VT_EMPTY;
  296. V_VT ( &continuous ) = VT_I4;
  297. V_VT ( &automatic ) = VT_I4;
  298. V_VT ( &medium ) = VT_I4;
  299. V_VT ( &thin ) = VT_I4;
  300. V_VT ( &none ) = VT_I4;
  301. V_VT ( &solid ) = VT_I4;
  302. V_VT ( &yellow ) = VT_I4;
  303. V_BOOL ( &no ) = FALSE;
  304. V_BOOL ( &yes ) = TRUE;
  305. V_I4 ( &dummy ) = 1;
  306. V_I4 ( &dummy0 ) = 0;
  307. V_BSTR ( &nullstring ) = SysAllocString ( OLESTR ("") );
  308. V_I4 ( &continuous ) = xlContinuous;
  309. V_I4 ( &automatic ) = xlAutomatic;
  310. V_I4 ( &medium ) = xlMedium;
  311. V_I4 ( &thin ) = xlThin;
  312. V_I4 ( &none ) = xlThin;
  313. V_I4 ( &solid ) = xlSolid;
  314. V_I4 ( &yellow ) = 6;
  315. }
  316. }
  317. return retval;
  318. }
  319. /////////////////////////////////////////////////////////////////////////
  320. //
  321. // Shutdown
  322. //
  323. /////////////////////////////////////////////////////////////////////////
  324. void
  325. ExcelClass::Shutdown (void)
  326. {
  327. Close_Workbook ();
  328. //
  329. // Free our interfaces
  330. //
  331. SAFE_DELETE (RangeObj);
  332. SAFE_DELETE (WorksheetObj);
  333. if (WorkbooksObj != NULL) {
  334. WorkbooksObj->Close ();
  335. SAFE_DELETE (WorksheetObj);
  336. }
  337. if (Application != NULL) {
  338. Application->Quit ();
  339. Application->ReleaseDispatch ();
  340. SAFE_DELETE (Application);
  341. }
  342. //
  343. // Dunno
  344. //
  345. VariantClear (&nullstring);
  346. return ;
  347. }
  348. /////////////////////////////////////////////////////////////////////////
  349. //
  350. // New_Workbook
  351. //
  352. /////////////////////////////////////////////////////////////////////////
  353. void
  354. ExcelClass::New_Workbook (const char *template_filename)
  355. {
  356. if (template_filename == NULL) {
  357. return ;
  358. }
  359. //
  360. // Configure a variant with the filename we wish to add
  361. //
  362. WideStringClass wide_filename;
  363. wide_filename.Convert_From (template_filename);
  364. VARIANT temp;
  365. V_VT (&temp) = VT_BSTR;
  366. V_BSTR (&temp) = ::SysAllocString (wide_filename);
  367. //
  368. // Create the new workbook
  369. //
  370. LPDISPATCH dispatch = WorkbooksObj->Add (temp);
  371. if (dispatch != NULL) {
  372. //
  373. // Create a new wrapper object for this workbook
  374. //
  375. WorkbookObj = new _Workbook (dispatch);
  376. Select_Active_Sheet ();
  377. }
  378. //
  379. // Free the variant's data
  380. //
  381. ::VariantClear (&temp);
  382. return ;
  383. }
  384. /////////////////////////////////////////////////////////////////////////
  385. //
  386. // Open_Workbookk
  387. //
  388. /////////////////////////////////////////////////////////////////////////
  389. void
  390. ExcelClass::Open_Workbook (const char *filename)
  391. {
  392. //
  393. // Attempt to open this workbook
  394. //
  395. LPDISPATCH dispatch = WorkbooksObj->Open (filename, dummy0, yes, dummy, nullstring,
  396. nullstring, yes, dummy, dummy, no, no, dummy, no);
  397. if (dispatch != NULL) {
  398. //
  399. // Wrap the dispatch pointer in a friendlier object
  400. //
  401. WorkbookObj = new _Workbook (dispatch);
  402. Select_Active_Sheet ();
  403. }
  404. return ;
  405. }
  406. /////////////////////////////////////////////////////////////////////////
  407. //
  408. // Save_Workbook
  409. //
  410. /////////////////////////////////////////////////////////////////////////
  411. void
  412. ExcelClass::Save_Workbook (const char *filename)
  413. {
  414. if (WorkbookObj == NULL) {
  415. return ;
  416. }
  417. VARIANT name, fileformat, rc;
  418. WideStringClass wide_filename;
  419. wide_filename.Convert_From (filename);
  420. V_VT (&name) = VT_BSTR;
  421. V_BSTR (&name) = SysAllocString (wide_filename);
  422. V_VT (&fileformat) = VT_I4;
  423. V_I4 (&fileformat) = xlWorkbookNormal;
  424. V_VT (&rc) = VT_I4;
  425. V_I4 (&rc) = xlLocalSessionChanges;
  426. WorkbookObj->SaveAs ( name, fileformat, nullstring, nullstring, no, no,
  427. xlNoChange, rc, no, empty, empty );
  428. VariantClear (&name);
  429. /*if (WorkbookObj != NULL) {
  430. WorkbookObj->Save ();
  431. }*/
  432. /*dispatch;
  433. VARIANT temp;
  434. V_VT ( &temp ) = VT_I4;
  435. V_I4 ( &temp ) = xlWBATWorksheet;
  436. if (CurrPath.Is_Empty () == false) {
  437. //
  438. // Check to see if the file still exists
  439. //
  440. if (::GetFileAttributes (CurrPath) != 0xFFFFFFFF) {
  441. WideStringClass wide_filename;
  442. wide_filename.Convert_From (CurrPath);
  443. //
  444. // Fill in the path of the file
  445. //
  446. V_VT (&temp) = VT_BSTR;
  447. V_BSTR (&temp) = ::SysAllocString (wide_filename);
  448. }
  449. }
  450. }
  451. //
  452. // Save the workbook and refresh our workbook object
  453. //
  454. LPDISPATCH dispatch = WorkbooksObj->Add (temp);
  455. if (dispatch != NULL) {
  456. WorkbookObj = new _Workbook (dispatch);
  457. }
  458. Select_Active_Sheet ();
  459. VariantClear (&temp);*/
  460. return ;
  461. }
  462. /////////////////////////////////////////////////////////////////////////
  463. //
  464. // Close_Workbook
  465. //
  466. /////////////////////////////////////////////////////////////////////////
  467. void
  468. ExcelClass::Close_Workbook (void)
  469. {
  470. //
  471. // Simply close and delete the workbook
  472. //
  473. if (WorkbookObj != NULL) {
  474. WorkbookObj->SetSaved (TRUE);
  475. WorkbookObj->Close (no, nullstring, no);
  476. SAFE_DELETE (WorkbookObj);
  477. }
  478. return ;
  479. }
  480. /////////////////////////////////////////////////////////////////////////
  481. //
  482. // Get_String
  483. //
  484. /////////////////////////////////////////////////////////////////////////
  485. bool
  486. ExcelClass::Get_String (int row, int col, WideStringClass &string)
  487. {
  488. bool retval = false;
  489. //
  490. // Get the cell's contents
  491. //
  492. VARIANT variant_value;
  493. if (Get_Cell (row, col, variant_value)) {
  494. //
  495. // Is this a string?
  496. //
  497. if (V_VT (&variant_value) == VT_BSTR) {
  498. string = V_BSTR (&variant_value);
  499. retval = true;
  500. } else if (V_VT (&variant_value) == VT_R4) {
  501. int value = (int)variant_value.fltVal;
  502. string.Format (L"%d", value);
  503. retval = true;
  504. } else if (V_VT (&variant_value) == VT_R8) {
  505. int value = (int)variant_value.dblVal;
  506. string.Format (L"%d", value);
  507. retval = true;
  508. } else if ( V_VT (&variant_value) == VT_I2 || V_VT (&variant_value) == VT_I4 ||
  509. V_VT (&variant_value) == VT_UI2 || V_VT (&variant_value) == VT_UI4)
  510. {
  511. string.Format (L"%d", variant_value.iVal);
  512. retval = true;
  513. }
  514. //
  515. // Free the variant data
  516. //
  517. ::VariantClear (&variant_value);
  518. }
  519. return retval;
  520. }
  521. /////////////////////////////////////////////////////////////////////////
  522. //
  523. // Set_String
  524. //
  525. /////////////////////////////////////////////////////////////////////////
  526. bool
  527. ExcelClass::Set_String (int row, int col, const WideStringClass &value)
  528. {
  529. //
  530. // Configure a variant with the string data we want to set
  531. //
  532. VARIANT variant_value;
  533. V_VT (&variant_value) = VT_BSTR;
  534. V_BSTR (&variant_value) = ::SysAllocString (value);
  535. //
  536. // Put the string into the cell
  537. //
  538. bool retval = Set_Cell (row, col, variant_value);
  539. //
  540. // Free the variant data
  541. //
  542. ::VariantClear (&variant_value);
  543. return retval;
  544. }
  545. /////////////////////////////////////////////////////////////////////////
  546. //
  547. // Get_Int
  548. //
  549. /////////////////////////////////////////////////////////////////////////
  550. bool
  551. ExcelClass::Get_Int (int row, int col, int &value)
  552. {
  553. bool retval = false;
  554. //
  555. // Get the cell's contents
  556. //
  557. VARIANT variant_value;
  558. if (Get_Cell (row, col, variant_value)) {
  559. //
  560. // Is this an integer?
  561. //
  562. if (V_VT (&variant_value) == VT_I4) {
  563. value = V_I4(&variant_value);
  564. retval = true;
  565. }
  566. //
  567. // Free the variant data
  568. //
  569. ::VariantClear (&variant_value);
  570. }
  571. return retval;
  572. }
  573. /////////////////////////////////////////////////////////////////////////
  574. //
  575. // Set_Int
  576. //
  577. /////////////////////////////////////////////////////////////////////////
  578. bool
  579. ExcelClass::Set_Int (int row, int col, int value)
  580. {
  581. //
  582. // Configure a variant with the integer data we want to set
  583. //
  584. VARIANT variant_value;
  585. V_VT (&variant_value) = VT_I4;
  586. V_I4 (&variant_value) = value;
  587. //
  588. // Put the integer into the cell
  589. //
  590. bool retval = Set_Cell (row, col, variant_value);
  591. //
  592. // Free the variant data
  593. //
  594. ::VariantClear (&variant_value);
  595. return retval;
  596. }
  597. /////////////////////////////////////////////////////////////////////////
  598. //
  599. // Select_Active_Sheet
  600. //
  601. /////////////////////////////////////////////////////////////////////////
  602. void
  603. ExcelClass::Select_Active_Sheet (void)
  604. {
  605. LPDISPATCH dispatch = Application->GetActiveSheet ();
  606. //
  607. // If possible, attach the new worksheet
  608. //
  609. if (dispatch != NULL) {
  610. WorksheetObj->ReleaseDispatch ();
  611. WorksheetObj->AttachDispatch (dispatch);
  612. }
  613. return ;
  614. }
  615. /////////////////////////////////////////////////////////////////////////
  616. //
  617. // Get_Cell
  618. //
  619. /////////////////////////////////////////////////////////////////////////
  620. bool
  621. ExcelClass::Get_Cell (int row, int col, VARIANT &result)
  622. {
  623. if (WorksheetObj == NULL) {
  624. return false;
  625. }
  626. bool retval = false;
  627. //
  628. // Generate the name of the cell we'll be using
  629. //
  630. WideStringClass cell_name;
  631. cell_name.Format (L"%c%d", 'A'+col , row + 1);
  632. //
  633. // Configure a variant object for use as a cell ID
  634. //
  635. VARIANT cell;
  636. V_VT (&cell) = VT_BSTR;
  637. V_BSTR (&cell) = ::SysAllocString (cell_name);
  638. //
  639. // Get the data
  640. //
  641. LPDISPATCH dispatch = WorksheetObj->GetRange (cell, cell);
  642. if (dispatch != NULL) {
  643. //
  644. // Retrieve the data from the range object
  645. //
  646. RangeObj->AttachDispatch (dispatch);
  647. result = RangeObj->GetValue ();
  648. RangeObj->ReleaseDispatch ();
  649. retval = true;
  650. }
  651. //
  652. // Free the variant data
  653. //
  654. ::VariantClear (&cell);
  655. return retval;
  656. }
  657. /////////////////////////////////////////////////////////////////////////
  658. //
  659. // Set_Cell
  660. //
  661. /////////////////////////////////////////////////////////////////////////
  662. bool
  663. ExcelClass::Set_Cell (int row, int col, const VARIANT &data)
  664. {
  665. if (WorksheetObj == NULL) {
  666. return false;
  667. }
  668. bool retval = false;
  669. //
  670. // Generate the name of the cell we'll be using
  671. //
  672. WideStringClass cell_name;
  673. cell_name.Format (L"%c%d", 'A'+col, row + 1);
  674. //
  675. // Configure a variant object for use as a cell ID
  676. //
  677. VARIANT cell;
  678. V_VT (&cell) = VT_BSTR;
  679. V_BSTR (&cell) = ::SysAllocString (cell_name);
  680. //
  681. // Get the cell range
  682. //
  683. LPDISPATCH dispatch = WorksheetObj->GetRange (cell, cell);
  684. if (dispatch != NULL) {
  685. //
  686. // Shove our new data into this range
  687. //
  688. RangeObj->AttachDispatch (dispatch);
  689. RangeObj->SetValue (data);
  690. RangeObj->ReleaseDispatch ();
  691. retval = true;
  692. }
  693. //
  694. // Free the variant data
  695. //
  696. ::VariantClear (&cell);
  697. return retval;
  698. }