下面我们通过一示例,来了解一下最常打交道的 Range 对象:

    1. /*关于[单元格区域(Range)]对象的测试*/
    2. function Range_Test() {
    3. {//1.Range 对象的获取
    4. let rangePathPrinter = rng => Console.log('详细地址:' +
    5. rng.Worksheet.Name + '/' + rng.Address());
    6. //1.1.Range 构造器
    7. //通过 new 获取 Range 对象时,默认指向的是 ActiveSheet 表
    8. var rngNew = new Range('I1');
    9. rangePathPrinter(rngNew);
    10. //1.2.通过 Application.InputBox() 方法
    11. //当用户选取了单元格区域并点击确定时,它返回一个 Range 对象
    12. //当用户未进行任何选取,或者点击了取消时,它返回 false
    13. var rngSelected = Application.InputBox(
    14. '请用鼠标框选单元格区域', '选取单元格区域', undefined,
    15. undefined, undefined, undefined, undefined, 8);
    16. if (rngSelected === false)
    17. alert('您未选取任何单元格区域!');
    18. else
    19. rangePathPrinter(rngSelected);
    20. //1.3.通过 Worksheet.Range() 方法获取,它获取的单元格区域
    21. // 是属于该 Worksheet(即工作表对象)的
    22. var rngWorksheet = ThisWorkbook.Worksheets.Item(
    23. ThisWorkbook.Worksheets.Count).Range('A1:A10');
    24. rangePathPrinter(rngWorksheet);
    25. //1.4.通过 Application.Range() 方法来获取,它也指向
    26. // ActiveSheet(即当前表)
    27. let rngApplication = Application.Range('A1');
    28. rangePathPrinter(rngApplication);
    29. }
    30. {//2.Range 的类型原型
    31. //由以下语句的结果可知,Range 函数只是一个工具,它
    32. //在 new 时,将 prototype 重定向了,它并不是真正的原型
    33. Console.log('constructor name : ' + rngNew.constructor.name);
    34. Console.log('is instance of Range? = ' + (rngNew instanceof Range));
    35. Console.log('is prototype same? = ' +
    36. (rngNew.__proto__ == rngWorksheet.__proto__));
    37. Console.log('is constructor same? = ' +
    38. (rngNew.constructor == rngWorksheet.constructor));
    39. }
    40. {//3.查看 Range 对象的所有成员
    41. let memberNames = Object.keys(rngNew);
    42. Console.log('property/method count : ' + memberNames.length);
    43. let counter = 0;
    44. memberNames = memberNames.sort();
    45. for(let name of memberNames) {
    46. let info = '[' + (++counter) + ']' + name;
    47. //不加try...catch...不行,因为为 member 取值可能出错
    48. try {
    49. let member = rngNew[name];
    50. if (/*这个条件判断不成功,不知为何*/
    51. member instanceof Function ||
    52. /*这个条件却可以,奇怪吧*/
    53. typeof member == 'function')
    54. Console.log(info + '(...)');
    55. else
    56. Console.log(info);
    57. } catch {
    58. Console.log(info);
    59. }
    60. }
    61. }
    62. {//4.通过 Value()/Value2 快捷读写单元格区域
    63. //4.1.只能通过 Value2 来写数据
    64. let bordersMaker = function(rng, color) {
    65. let indices = [xlEdgeLeft, xlEdgeTop,
    66. xlEdgeBottom, xlEdgeRight,
    67. xlInsideHorizontal, xlInsideVertical];
    68. for (let index of indices) {
    69. (obj=>{
    70. obj.Weight = xlThin;
    71. obj.LineStyle = xlContinuous;
    72. obj.Color = color;
    73. })(rng.Borders.Item(index));
    74. }
    75. }
    76. //4.1.1.当向包含多个单元格的单元格区域,写入单个值时,
    77. // 每一个单元格都将得到这个值
    78. let rngSingleValueWriteTo = new Range('A1:B2,D1,F1:G3');
    79. let red = 255; //红色
    80. bordersMaker(rngSingleValueWriteTo, red);
    81. rngSingleValueWriteTo.Value2 = '单个值';
    82. //4.1.2.当向一个单元格区域写入一个一维数组时,它通过遍历将数组
    83. // 中的元素赋值给单元格区域的单元格:
    84. // 1.它总是对应的将第N个元素赋值给每行的第N个单元格;
    85. // 2.如果它的元素个数多于行的单元格个数,多出的元素将被丢弃;
    86. // 3.如果它的元素个数少于行的单元格个数,缺少数据的单元格,将
    87. // 被填充以 "#N/A" 这个错误
    88. let rngSingleDimensionalArrayWriteTo =
    89. new Range('A4:B6,D4,F5:I6');
    90. let blue = 12611584; //蓝色
    91. bordersMaker(rngSingleDimensionalArrayWriteTo, blue);
    92. rngSingleDimensionalArrayWriteTo.Value2 = ['a', 'b', 'c'];
    93. //4.1.3.当向一个单元格区域写入一个多维数组时,逻辑混乱,
    94. // 不要这么调用
    95. let rngMultiDimensionalArrayWriteTo =
    96. new Range('A8:B10,D8,F8:I9');
    97. let black = 0; //黑色
    98. bordersMaker(rngMultiDimensionalArrayWriteTo, black);
    99. rngMultiDimensionalArrayWriteTo.Value2 =
    100. [['a', 'b', 'c'], [1, 2, 3], [false, true, true]];
    101. //4.2.读取全部单元格区域数据
    102. //可以一次性取得单元格区域对象的所有单元格的值,它们会被
    103. //组织成一个数组返回,这个数组按照先列后行的数据读存单元格
    104. //区域中所有单元格的值;
    105. let rngData = new Range('A12:C15');
    106. rngData.Rows.Item(1).Value2 = ['A', 'B', 'C'];
    107. rngData.Rows.Item(2).Value2 = ['D', 'E', 'F'];
    108. rngData.Rows.Item(3).Value2 = ['G', 'H', 'I'];
    109. //读取全部
    110. let vsData = rngData.Value2;
    111. Console.log(JSON.stringify(vsData));
    112. //少读一列
    113. let vsDataPart = rngData.Cells.Item(1)
    114. .Resize(3, 2).Value2;
    115. Console.log(JSON.stringify(vsDataPart))
    116. //读单行数据
    117. let vsDataRow = rngData.Rows.Item(1).Value2;
    118. Console.log(JSON.stringify(vsDataRow));
    119. //读单列数据
    120. let vsDataColumn = rngData.Columns.Item(1).Value2;
    121. Console.log(JSON.stringify(vsDataColumn));
    122. //由以上例子的输出可知,只有单行单元格区域的数据,
    123. //可以一次无误地将所有数据读取到一个数组中;
    124. //而且只要你的单元格区域包含多个单元格,读取到的
    125. //一定会是一个二维数组
    126. //综上所述,请在快捷读取单元格区域数据时,只按行单行
    127. //单行的读取
    128. }
    129. {/*5.通过 Value()/Value2 读写特殊值:
    130. //5.1.Date 类型
    131. 后者将 Date 与 Currency 类型的数据以 Double 类型返回
    132. VBA 在这方面处理得比较好,因为它本身支持的 Date/Currency 类型是与 Excel
    133. 的同名数据类型是对等的;而 JSA 的 Date 类型与 Excel 的 Date 类型完全不对
    134. 等,至于 Currency 类型,JSA 则根本就不支持*/
    135. let now = new Date(Date.now());
    136. let cell = rngNew;
    137. cell.Clear();
    138. //通过赋值加设置数据格式的方式,可以向单元格输入日期值
    139. cell.Value2 = now;
    140. cell.NumberFormatLocal = 'yyyy/mm/dd hh:MM:ss;@';
    141. Console.log(cell.Value2.constructor.name);//Number
    142. Console.log(cell.Value().constructor.name);//Date
    143. let dtValue = cell.Value();
    144. //JSA日期是带时区的,Excel 的不带时区
    145. Console.log(now);
    146. Console.log(now.toLocaleString());
    147. Console.log(dtValue);
    148. Console.log(dtValue.toLocaleString());
    149. //设置到单元格的日期数据会丢失毫秒的精度
    150. Console.log(now.valueOf());
    151. Console.log(dtValue.valueOf());
    152. Console.log(now - dtValue == now.getMilliseconds());
    153. //所以在 JSA 与 Excel 有日期时间数据交换时,要注意时区与毫秒精度方面的影响
    154. }
    155. }

    其输出如下:

    1. 详细地址:Sheet2/$I$1
    2. 详细地址:Sheet1/$H$32
    3. 详细地址:Sheet2/$A$1:$A$10
    4. 详细地址:Sheet2/$A$1
    5. constructor name : Range
    6. is instance of Range? = false
    7. is prototype same? = true
    8. is constructor same? = true
    9. property/method count : 187
    10. [1]Activate(...)
    11. [2]AddComment(...)
    12. [3]AddIndent
    13. [4]Address(...)
    14. [5]AddressLocal(...)
    15. [6]AdvancedFilter(...)
    16. [7]AllocateChanges(...)
    17. [8]AllowEdit
    18. [9]Application
    19. [10]ApplyNames(...)
    20. [11]ApplyOutlineStyles(...)
    21. [12]Areas
    22. [13]AutoComplete(...)
    23. [14]AutoFill(...)
    24. [15]AutoFilter(...)
    25. [16]AutoFit(...)
    26. [17]AutoFormat(...)
    27. [18]AutoOutline(...)
    28. [19]BorderAround(...)
    29. [20]Borders
    30. [21]Calculate(...)
    31. [22]CalculateRowMajorOrder(...)
    32. [23]Cells
    33. [24]Characters(...)
    34. [25]CheckSpelling(...)
    35. [26]Clear(...)
    36. [27]ClearComments(...)
    37. [28]ClearContents(...)
    38. [29]ClearFormats(...)
    39. [30]ClearHyperlinks(...)
    40. [31]ClearNotes(...)
    41. [32]ClearOutline(...)
    42. [33]Column
    43. [34]ColumnDifferences(...)
    44. [35]ColumnWidth
    45. [36]Columns
    46. [37]Comment
    47. [38]Consolidate(...)
    48. [39]Copy(...)
    49. [40]CopyFromRecordset(...)
    50. [41]CopyPicture(...)
    51. [42]Count
    52. [43]CountLarge
    53. [44]CreateNames(...)
    54. [45]CreatePublisher(...)
    55. [46]Creator
    56. [47]CurrentArray
    57. [48]CurrentRegion
    58. [49]Cut(...)
    59. [50]DataSeries(...)
    60. [51]Delete(...)
    61. [52]Dependents
    62. [53]DialogBox(...)
    63. [54]DirectDependents
    64. [55]DirectPrecedents
    65. [56]Dirty(...)
    66. [57]DiscardChanges(...)
    67. [58]DisplayFormat
    68. [59]EditionOptions(...)
    69. [60]End(...)
    70. [61]EntireColumn
    71. [62]EntireRow
    72. [63]Errors
    73. [64]ExportAsFixedFormat(...)
    74. [65]FillDown(...)
    75. [66]FillLeft(...)
    76. [67]FillRight(...)
    77. [68]FillUp(...)
    78. [69]Find(...)
    79. [70]FindNext(...)
    80. [71]FindPrevious(...)
    81. [72]FlashFill(...)
    82. [73]Font
    83. [74]FormatConditions
    84. [75]Formula
    85. [76]FormulaArray
    86. [77]FormulaHidden
    87. [78]FormulaLabel
    88. [79]FormulaLocal
    89. [80]FormulaR1C1
    90. [81]FormulaR1C1Local
    91. [82]FunctionWizard(...)
    92. [83]GetRangeEx(...)
    93. [84]GoalSeek(...)
    94. [85]Group(...)
    95. [86]HasArray
    96. [87]HasFormula
    97. [88]Height
    98. [89]Hidden
    99. [90]HorizontalAlignment
    100. [91]Hyperlinks
    101. [92]ID
    102. [93]IndentLevel
    103. [94]Insert(...)
    104. [95]InsertIndent(...)
    105. [96]Interior
    106. [97]Item(...)
    107. [98]Justify(...)
    108. [99]Left
    109. [100]ListHeaderRows
    110. [101]ListNames(...)
    111. [102]ListObject
    112. [103]LocationInTable
    113. [104]Locked
    114. [105]MDX
    115. [106]Merge(...)
    116. [107]MergeArea
    117. [108]MergeCells
    118. [109]Name
    119. [110]NavigateArrow(...)
    120. [111]Next
    121. [112]NoteText(...)
    122. [113]NumberFormat
    123. [114]NumberFormatLocal
    124. [115]Offset(...)
    125. [116]Orientation
    126. [117]OutlineLevel
    127. [118]PageBreak
    128. [119]Parent
    129. [120]Parse(...)
    130. [121]PasteSpecial(...)
    131. [122]Phonetic
    132. [123]Phonetics
    133. [124]PivotCell
    134. [125]PivotField
    135. [126]PivotItem
    136. [127]PivotTable
    137. [128]Precedents
    138. [129]PrefixCharacter
    139. [130]Previous
    140. [131]PrintOut(...)
    141. [132]PrintPreview(...)
    142. [133]QueryTable
    143. [134]Range(...)
    144. [135]RangeEx
    145. [136]ReadingOrder
    146. [137]RemoveDuplicates(...)
    147. [138]RemoveSubtotal(...)
    148. [139]Replace(...)
    149. [140]Resize(...)
    150. [141]Row
    151. [142]RowDifferences(...)
    152. [143]RowHeight
    153. [144]Rows
    154. [145]Run(...)
    155. [146]Select(...)
    156. [147]ServerActions
    157. [148]SetPhonetic(...)
    158. [149]Show(...)
    159. [150]ShowDependents(...)
    160. [151]ShowDetail
    161. [152]ShowErrors(...)
    162. [153]ShowPrecedents(...)
    163. [154]ShrinkToFit
    164. [155]SmartTags
    165. [156]Sort(...)
    166. [157]SortSpecial(...)
    167. [158]SoundNote
    168. [159]SparklineGroups
    169. [160]Speak(...)
    170. [161]SpecialCells(...)
    171. [162]Style
    172. [163]SubscribeTo(...)
    173. [164]Subtotal(...)
    174. [165]Summary
    175. [166]Table(...)
    176. [167]Text
    177. [168]TextToColumns(...)
    178. [169]Top
    179. [170]UnMerge(...)
    180. [171]Ungroup(...)
    181. [172]UseStandardHeight
    182. [173]UseStandardWidth
    183. [174]Validation
    184. [175]Value(...)
    185. [176]Value2
    186. [177]VerticalAlignment
    187. [178]Width
    188. [179]Worksheet
    189. [180]WrapText
    190. [181]XPath
    191. [182]_BorderAround(...)
    192. [183]_Default(...)
    193. [184]_NewEnum
    194. [185]_PasteSpecial(...)
    195. [186]_PrintOut(...)
    196. [187]__PrintOut(...)
    197. [["A","D","G"],[null,"B","E"],["H",null,"C"],["F","I",null]]
    198. [["A","D"],["G","B"],["E","H"]]
    199. [["A","B","C"]]
    200. [["A"],["D"],["G"],[null]]
    201. Number
    202. Date
    203. 2021/8/22 17:03:34
    204. 2021/8/23 上午1:03:34
    205. 2021/8/22 17:03:34
    206. 2021/8/23 上午1:03:34
    207. 1629651814310
    208. 1629651814000
    209. true