LibreOffice宏报错修复:从单列生成唯一值计数双列表
解决LibreOffice宏报错“Property or method not found: setValue”
错误原因分析
- 范围对象调用单个单元格方法:原代码中
oTargetRange.setValue("Unique Value"),oTargetRange是B64:C64的单元格范围,而setValue/setString是单个XCell对象的专属方法,范围对象无此方法,直接调用导致报错。 - UniqueElementsContainer用法错误:
com.sun.star.container.UniqueElementsContainer仅用于存储唯一元素,无法关联对应计数,原代码用它存值和计数的逻辑完全错误,会导致后续取值混乱。 - 单元格遍历方式错误:
For Each oCell In oSourceRange无法正确遍历范围中的每个单元格,必须通过行索引逐个获取单元格。 - 目标单元格索引错误:
getCellByPosition(列索引, 行索引)的索引从0开始(A列=0,行1=0),原代码的位置计算完全错误,会导致数据写入错误区域。
修正后的宏代码
Sub GenerateUniqueValueTable() Dim oSheetA As Object Dim oSheetB As Object Dim oSourceRange As Object Dim oCell As Object Dim oDict As Object Dim i As Long Dim sCellValue As String Dim vKeys As Variant Dim j As Long ' 获取源工作表和源范围 oSheetA = ThisComponent.getSheets().getByName("BD-direta") oSourceRange = oSheetA.getCellRangeByName("P1:P2047") ' 获取目标工作表 oSheetB = ThisComponent.Sheets.getByName("Estatistica") ' 设置标题行(B64和C64) oSheetB.getCellByPosition(1, 63).setString("Unique Value") ' B64:列索引1,行索引63(索引从0开始) oSheetB.getCellByPosition(2, 63).setString("Count") ' C64:列索引2,行索引63 ' 创建字典存储唯一值和计数 oDict = CreateObject("Scripting.Dictionary") ' 遍历源范围的每个单元格 For i = 0 To oSourceRange.getRows().getCount() - 1 oCell = oSourceRange.getCellByPosition(0, i) ' P列是源范围的第0列 sCellValue = Trim(oCell.String) ' 去除首尾空格,避免空字符串或重复值 If sCellValue <> "" Then ' 跳过空单元格 If oDict.Exists(sCellValue) Then oDict(sCellValue) = oDict(sCellValue) + 1 Else oDict.Add sCellValue, 1 End If End If Next i ' 获取字典的所有键,准备写入目标表 vKeys = oDict.Keys() ' 写入唯一值和计数到B65:Cxx起始位置 For j = 0 To UBound(vKeys) ' 写入唯一值到B列:列索引1,行索引64+j(B65开始) oSheetB.getCellByPosition(1, 64 + j).setString(vKeys(j)) ' 写入计数到C列:列索引2,行索引64+j oSheetB.getCellByPosition(2, 64 + j).setValue(oDict(vKeys(j))) Next j End Sub
核心修正点
- 改用
Scripting.Dictionary存储唯一值(键)和计数(值),逻辑清晰且适配键值对场景。 - 直接通过单个单元格索引设置标题,避免范围对象调用单个单元格方法的错误。
- 正确遍历源单元格,跳过空值避免无效计数。
- 修正目标单元格索引计算,确保数据从B65(标题行下一行)开始正确写入。
内容的提问来源于stack exchange,提问作者Deodato Cardoso
相关产品推荐
相关产品推荐

