旧的文章,就不改内容了,2021写的。
好久没写文章了,年底了,都在忙报表和预算等等的事情。元旦放假三天,终于可以休息一下,多余的时间思考点事情。同时最近想由VBA切换到WPS js,也想练练手,毕竟现在人手一个WPS,Excel真的不香了。
电池数据挖掘
很久之前就想过要对设备的数据进行挖掘一下,如设备的损耗啊、数据的精度呀、设备的故障判定呀等等方向。我的想法比较简单,先从动环拿到数据,一整年的数据,进行筛选和汇总,查看各个点的趋势和变化。日常动环的数据只有告警值,但是不能体现变化状态。同时由于电池的参数变化缓慢,没有拿多个月的数据进行对比显示不出来趋势。
实际操作
动环导出的数据格式如下:
主要获取的是单组电池的每节电池电压和内阻最大值,电压和内阻可以判定整整组的离散性和趋势,同时长期电压过高容易让电池发热。内阻是否逐步增大,以及增大的趋势。数据源说明,单组电池120节,每节2V。数据量为一年,导出每月的1日的数据,当然也可以导出365天的数据进行跑程序,只是时间久一点而已。
跑数据演示
数据处理还是十分快的。(5787-3)*12=69408,将近7万条数据,半分钟不到就能筛选完成。
结果分析
电压数据结果还是比较好的,没有离散太厉害的电池,并且是短时间电压比较高的情况,可能和季度充放电有关系。同时说明电压高的电池在充电的时候内阻大,分到的电压更高,说明这几个电池的性能会比其他的稍微差一点,可以多多给予他们关注。
内阻数据就也是类似的反馈,有一节电池的内阻会一直偏大,但是周期观察还是正常的,内阻较大可以检查巡检仪或者螺丝紧固的问题,放电的时候发热量就会更大,需要检查螺丝的松紧情况。其中,100#的电池内阻一直处于增长的状态,有1月份的0.29Ω一直增长到12月的0.33Ω,增长了13.8%。趋势很明显,需要重点关注,必要的时候可以让厂家进行更换。综合该组电池整体运行良好,个别电池需要关注后续的变化。部分内阻大的电池维护的时候检查一下螺丝紧固情况。
参考电池厂家给的0.29mΩ的标准,电池阻值还是很不错的,基本都在范围内。
电池内阻标准和实测
代码实现
代码是WPSjs宏编写,只能用在WPS上,Excel不能运行。
function 提取电池电压和内阻值(){
var batDic = {};
for(var counter =1;counter<=120;counter++)//初始化字典
{
key = '单体电压' + counter + '#';//不要使用batDic.key=counter创建,会创建失败
batDic[key]=0;
}
for(var counter =1;counter<=120;counter++)//初始化字典,为了方便输出时的顺序
{
key = '单体内阻' + counter + '#';
batDic[key]=0;
}// ------------------------读取数据
let shtData = Application.Worksheets.Item('Chart')//此处用名字和序号都不怎么好。WPS没有Excel的sheet1的写法
endRow = shtData.Range('c65336').End(xlUp).Row;
HvdcAndDate = shtData.Range('b4').Value2+'('+shtData.Range('f4').Value2.slice(0,10)+')'//区分HVDC编号和日期,懒得加定位了
var rng = shtData.Range('c4:c' + endRow);
var rng1 = shtData.Range('e4:e' + endRow);
var batName = rng.Value2;
var batValue = rng1.Value2;
// ------------------------处理数据,提取最大值
for (var b in batName)
{
batValue[b]=batValue[b]*1 //文本转数字,导出的数据是文本
key = batName[b]//要赋值,否则打印不出来,也无法判断,好坑人
if(batDic.hasOwnProperty(key))//判断键是否存在
{
if (batValue[b]>batDic[key])
{
batDic[key]=batValue[b]
}
}
}// for(var key in batDic)// {//// Debug.Print(key+':'+batDic[key])// }//---------------------写入数据//outputFileName = Application.ActiveWorkbook.Name输出数据(batDic,HvdcAndDate)//---------------------
batDic = null;
rng = null;
rng1=null;
初始化标题()}function 输出数据(Dic,name){
Application.Workbooks.Item(outputFileName).Activate();// var batDic = {'k1':'v1','k2':'v2','k3':'v3'};
var batDic = Dic;//电池的字典数据
let shtRes = Application.Worksheets.Item('结果')
endRow = shtRes.Range('b65336').End(xlUp).Row;
let counter = 0;
shtRes.Cells.Item(endRow+1, counter+1).Value2=name//HVDC的名称和日期组合
for(var key in batDic)
{
shtRes.Cells.Item(endRow+1, counter+2).Value2=batDic[key]
counter=counter+1
}}function 初始化标题(){
let shtRes = Application.Worksheets.Item('结果')
if (shtRes.Cells.Item(1, 2).Value2!='单体电压1#')
{
shtRes.Cells.Item(1, 1).Value2='时间'
for(var counter =1;counter<=120;counter++)
{
title = '单体电压' + counter + '#';
shtRes.Cells.Item(1, counter+1).Value2=title
}
for(var counter =1;counter<=120;counter++)
{
title= '单体内阻' + counter + '#';
shtRes.Cells.Item(1, counter+1+120).Value2=title
}
}
shtRes.Columns.Item('A:ii').AutoFit();
shtRes.Columns.Item('A:ii').HorizontalAlignment = xlHAlignCenter;}function 选择文件()
{// 2022.1.2
let fdfs = Application.FileDialog(msoFileDialogFilePicker)
fdfs.AllowMultiSelect = true
fdfs.InitialFileName = 'C:\*.xl*'
if (fdfs.Show()==-1)
{
var s =fdfs.SelectedItems
// Debug.Print(s.Item(1))
for (var ss=1 ;ss<=s.Count;ss++)
{
Application.DisplayAlerts = false;
f = s.Item(ss);
Workbooks.Open(f);
提取电池电压和内阻值()
Workbooks.Item(f).Close();
Application.DisplayAlerts = true;// Debug.Print(s.Item(ss))
}
}}function Workbook_Open(){
outputFileName = Application.ActiveWorkbook.Name
//创建全局变量,用于输出数据汇总
var res = MsgBox('是否开始进行电池电压和内阻文件选择?',jsOKCancel,'运行提示');
if (res==1)
{
清理旧数据和改名()
Application.ScreenUpdating = false
选择文件() //自动运行
Application.ScreenUpdating =true
生成电压线表()
生成内阻线表()
}
ActiveWorkbook.Save()}function 清理旧数据和改名(){
Application.Worksheets.Item('结果').Range('a1:ii150').Clear()
let sht = Application.Worksheets.Item('结果')
shape_num = sht.Shapes.Count
for(let i=1;i < shape_num+1;i++)
{
sht.Shapes.Item(1).Delete()
}}function 生成内阻线表(){
let co = Application.Sheets.Item('结果').ChartObjects().Add(800, 220, 800, 400)
let sht = Application.Worksheets.Item('结果')//此处用名字和序号都不怎么好。WPS没有Excel的sheet1的写法
endRow = sht.Range('c65336').End(xlUp).Row;
co.Chart.ChartWizard(Worksheets.Item('结果').Range(Cells(1,122),Cells(endRow,242)),xl3DLine, 6, xlColumns, 1, 1, 1,'BAT内阻','日期','Ω')//1,1,1设置横纵系列名称
co.Chart.Axes().Item(xlValue).MinimumScale = 0.2
co.Chart.Axes().Item(xlValue).MaximumScale = 0.4
for(var c=1;c<co.Chart.SeriesCollection().Count;c++)//设置平滑曲线
{
co.Chart.SeriesCollection(c).Smooth = true
}
ActiveWorkbook.Save()}function 生成电压线表(){
let co = Application.Sheets.Item('结果').ChartObjects().Add(0, 220, 800, 400)
let sht = Application.Worksheets.Item('结果')//此处用名字和序号都不怎么好。WPS没有Excel的sheet1的写法
endRow = sht.Range('c65336').End(xlUp).Row;
co.Chart.ChartWizard(Worksheets.Item('结果').Range(Cells(1,1),Cells(endRow,121)),xl3DLine, 6, xlColumns, 1, 1, 1,'BAT电压','日期','伏')//1,1,1设置横纵系列名称
co.Chart.Axes().Item(xlValue).MinimumScale = 2.22
co.Chart.Axes().Item(xlValue).MaximumScale = 2.28
for(var c=1;c<co.Chart.SeriesCollection().Count;c++)//设置平滑曲线
{
co.Chart.SeriesCollection(c).Smooth = true
}
ActiveWorkbook.Save()}
联系客服