Referencer.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. using Biff8Excel.Interfaces;
  6. namespace Biff8Excel.Formulas
  7. {
  8. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
  9. struct sReferencer1
  10. {
  11. [MarshalAs(UnmanagedType.U1, SizeConst = 1)] public byte area;
  12. public ushort firstrow;
  13. public ushort lastrow;
  14. public ushort firstcol;
  15. public ushort lastcol;
  16. }
  17. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
  18. struct sReferencer2
  19. {
  20. [MarshalAs(UnmanagedType.U1, SizeConst = 1)] public byte area;
  21. public ushort externIndex;
  22. public ushort firstrow;
  23. public ushort lastrow;
  24. public ushort firstcol;
  25. public ushort lastcol;
  26. }
  27. public class Referencer
  28. {
  29. const byte tRef = 0x44;
  30. const byte tRef3D = 0x5A;
  31. const byte tArea = 0x25;
  32. const byte tArea3D = 0x3B;
  33. IExternSheet m_externSheet;
  34. public Referencer()
  35. {
  36. }
  37. public IExternSheet ExternSheet
  38. {
  39. set { m_externSheet = value; }
  40. }
  41. private byte[] WriteAreaNoSheets(string cell1, string cell2)
  42. {
  43. sReferencer1 reference;
  44. reference.area = tArea;
  45. reference.firstrow = Globals.ConvertRowStringToNum(cell1);
  46. reference.firstcol = Globals.ConvertColStringToNum(cell1);
  47. reference.lastrow = Globals.ConvertRowStringToNum(cell2);
  48. reference.lastcol = Globals.ConvertColStringToNum(cell2);
  49. // not using Absolute positions ("$") character
  50. reference.firstcol = (ushort)(reference.firstcol | 0x8000 | 0x4000);
  51. reference.lastcol = (ushort)(reference.lastcol | 0x8000 | 0x4000);
  52. return Globals.GetStructToBytes(reference);
  53. }
  54. private byte[] WriteAreaWithSheets(ushort externIndex, string cell1, string cell2)
  55. {
  56. sReferencer2 reference;
  57. reference.area = tArea3D;
  58. reference.externIndex = externIndex;
  59. reference.firstrow = Globals.ConvertRowStringToNum(cell1);
  60. reference.firstcol = Globals.ConvertColStringToNum(cell1);
  61. reference.lastrow = Globals.ConvertRowStringToNum(cell2);
  62. reference.lastcol = Globals.ConvertColStringToNum(cell2);
  63. // not using Absolute positions ("$") character
  64. reference.firstcol = (ushort)(reference.firstcol | 0x8000 | 0x4000);
  65. reference.lastcol = (ushort)(reference.lastcol | 0x8000 | 0x4000);
  66. return Globals.GetStructToBytes(reference);
  67. }
  68. private byte[] WriteRefNoSheets(string cell)
  69. {
  70. byte[] b = new byte[5];
  71. ushort row, col;
  72. row = Globals.ConvertRowStringToNum(cell);
  73. col = Globals.ConvertColStringToNum(cell);
  74. // not using Absolute positions ("$") character
  75. col = (ushort)((ushort)col | 0x8000 | 0x4000);
  76. b[0] = tRef;
  77. BitConverter.GetBytes(row).CopyTo(b, 1);
  78. BitConverter.GetBytes(col).CopyTo(b, 3);
  79. return b;
  80. }
  81. private byte[] WriteRefWithSheets(ushort externIndex, string cell)
  82. {
  83. byte[] b = new byte[7];
  84. ushort row, col;
  85. row = Globals.ConvertRowStringToNum(cell);
  86. col = Globals.ConvertColStringToNum(cell);
  87. // not using Absolute positions ("$") character
  88. col = (ushort)(col | 0x8000 | 0x4000);
  89. b[0] = tRef3D;
  90. BitConverter.GetBytes(externIndex).CopyTo(b, 1);
  91. BitConverter.GetBytes(row).CopyTo(b, 3);
  92. BitConverter.GetBytes(col).CopyTo(b, 5);
  93. return b;
  94. }
  95. public byte[] Serialize(string reference)
  96. {
  97. string sheet1, sheet2, sheets;
  98. string cell1, cell2, cells;
  99. string s;
  100. int pos;
  101. ushort x, idx, token;
  102. sheet1 = sheet2 = sheets = "";
  103. cell1 = cell2 = cells = "";
  104. idx = 0;
  105. if (reference == null)
  106. throw new ArgumentNullException("reference", " not null");
  107. // See if this ref is part of a built in function eg SUM(Sheet1!A1:A2)
  108. // we only want the Sheet1!A1:A2 part
  109. pos = reference.IndexOf("(");
  110. if (pos > -1)
  111. {
  112. //reference = reference.Substring(pos + 1);
  113. //reference = reference.Substring(0, reference.Length - 1); //remove the closing bracket
  114. //µÃµ½À¨ºÅÖеÄÄÚÈÝ
  115. reference = reference.Substring(pos + 1, reference.Length - 2 - pos);
  116. }
  117. pos = reference.IndexOf("!");
  118. if (pos > -1) // we have sheet refs
  119. {
  120. //split out the sheet(s)
  121. x = (ushort)(pos - 1);
  122. do
  123. {
  124. s = reference.Substring(x, 1);
  125. if (s == "(" || s == "$")
  126. break;
  127. sheets += s;
  128. x--;
  129. } while (x > 0);
  130. sheets = Globals.StrReverse(sheets);
  131. // how many sheets are their
  132. pos = (ushort)sheets.IndexOf(":");
  133. if (pos > -1)
  134. {
  135. sheet1 = sheets.Substring(0, pos - 1);
  136. if (sheets.Substring(pos + 1) == "$")
  137. sheet2 = sheets.Substring(pos + 2);
  138. else
  139. sheet2 = sheets.Substring(pos + 1);
  140. }
  141. else
  142. {
  143. sheet1 = sheets;
  144. sheet2 = sheets;
  145. }
  146. // Get an index into the Extern Sheet record
  147. idx = m_externSheet.AddEntry(sheet1, sheet2);
  148. }
  149. // get the cell references
  150. pos =reference.IndexOf("!");
  151. if (pos > -1)
  152. cells = reference.Substring(pos + 1);
  153. else
  154. cells = reference;
  155. // Is it an AreaRef (A1:B1) or CellRef (A1).
  156. pos = cells.IndexOf(":");
  157. if (pos > -1)
  158. {
  159. token = (sheet1.Length == 0 ? tArea : tArea3D);
  160. cell1 = cells.Substring(0, pos );
  161. cell2 = cells.Substring(pos + 1);
  162. if (token == tArea)
  163. return WriteAreaNoSheets(cell1, cell2);
  164. else
  165. return WriteAreaWithSheets(idx, cell1, cell2);
  166. }
  167. else
  168. {
  169. token = (sheet1.Length == 0 ? tRef : tRef3D);
  170. cell1 = cells;
  171. if (token == tRef)
  172. return WriteRefNoSheets(cell1);
  173. else
  174. return WriteRefWithSheets(idx, cell1);
  175. }
  176. }
  177. }
  178. }