概述
前言
随着Simulink的使用,数据字典已经越来越重要,这几天我写了一个关于表格数据生成数据字典的方法,有兴趣的可以学习下。部分地方我还不熟练,有写地方可能存在绕弯的情况,不过对于初学者还是比较有帮助的
下边就给大家拆解分析下如何实现的
思路
具体就是将表格数据导入到matlab中,然后选择其中的数据通过循环语句进行写入数据字典,因为bus信号的写入格式特殊,所以先通过脚本创建一个专门的bus脚本,最后调用这个脚本完成bus数据从Workspace数据导入到数据字典
分析脚本
这一段是选择文件的标准格式,之前我也在其他的脚本中使用过这个格式
[filetxt,pathtxt] = uigetfile('*.*','Please select an image');%文件筐,选择文件
if(filetxt)
filetxt = strcat(pathtxt,filetxt);
filetxt = lower(filetxt);%一致的小写字母形式
else
msgbox('Please select an image');
return; %退出程序
end
这部分是为了读取表中数据,
[data,txt]=xlsread(filetxt,'signal');%读取表格内容
A=~cellfun(@isempty,txt);%读取的内容按照0和1辨认
C = readmatrix(filetxt);%获取选择文件的数值信息
上图是我之前编辑好的一个数据信息,同过上边的函数将数据写入到matlab中
这部分是获取我选中文件的文件名,为了后边的数据字典和脚本做文件名
同时求取数据的行数,为后边的循环语句
name=strsplit(filetxt,'');%将读取的路径分割,这一步是为了找到打开文件的名称
fine=name(length(name));%求长度,为了选取数组最后一个数据
aaa=strsplit(string(fine),'.');%获取文件名称,同时去掉后缀
fined=aaa(1);
Excelname = fined; %获取表格名称
ccc=append(fined,'.sldd');%创建.sldd的名称
inportLength=sum(A(:,2));%求A列的长度
dictionaryObj1 = Simulink.data.dictionary.create(ccc); %创建一个数据字典
着部分是循环语句,循环周期已经通过行数得出,这部分将数据写入到字典中。。循环语句中函数通过matlab的help就可以找到
for i=2:inportLength%循环语句
Signal_test = Simulink.Signal;
Signal_test.DataType = string(txt(i,2)); %类型
Signal_test.InitialValue = string(C(i-1,4)); %初始值
Signal_test.StorageClass = string(txt(i,5)); %存储方式
Signal_test.Dimensions = C(i-1,3); %维度
dictionaryObj= Simulink.data.dictionary.open(ccc);%打开数据字典
sectionObj = getSection(dictionaryObj,'Design Data');%存入数据
addEntry(sectionObj,string(txt(i,1)),Signal_test);%加入信号
end
获取BUS页相关数据同时处理好新建的脚本名称
[data1,txt1]=xlsread(filetxt,'Bus');%读取表中BUS页的信号
B=~cellfun(@isempty,txt1);%读取01值
inportLength1=sum(B(:,2));%读取长度
Excel_name = Excelname; %获取表格名称
disp(Excel_name);%创建
mfile_name = strcat(Excel_name,'Var.m'); %编写要创建的脚本文件名:
文件打开,第一行编写空格
fid = fopen(mfile_name,'w');%打开文件
fprintf(fid,'n');%文件中空格
这里说明下为什么要创建一个新的脚本,bus的信号导入函数需要添加bus名称,而函数名称是不能通过文本转变的,这里给大家看一个示例:
这里可以看到这是一个bus信息导入到workspace的函数因为AAA_signal(1)部分是可变的,所以不能通过现在的脚本去实现上边的格式,所以只能通过新建立脚本,最后主函数调用这个脚本来完成bus信号添加
这一部分比较长,原本可以缩减,但是这么看比较清除如何实现的:
这是一个循环语句,针对与bus进行循环,随后判断哪里是有数据的,这里我们只判断1列,这样就可以获取bus的名称,没有名称的地方,我们认为是bus的元素,如果是bus信号的话,这里记录一个全局变量,供没有名称的bus元素使用
因为在格式中所有的元素都需要bus名称作为前缀,
这里大家可以看的到,我在AAA后边加上一个“_Signal”字样,这里是为什么呢,因为每个bus在写入完后,需要添加
这个语句,这个语句中的开头是bus的最终名称,而AAA_Signal需要特定格式满足,所以这里进行了字符串添加
namess=strcat(names,'_signal');%这里主要是区分bus格式的头和BUS名
for i=2:inportLength1%循环语句
global names;%这里需要定义一个全局变量,为主要是下边的if else使用
if (strcmp(char(yyy(i,1)),'true'))%判断yyy的数值是不是有值情况
names=txt1(i,1);%上传一个全局变量名称,为了后边的BUS格式使用
namess=strcat(names,'_signal');%这里主要是区分bus格式的头和BUS名
z=49;%这里通过ascii码转为1
zz=char(z);%转文本
str_tmp = strcat(char(namess),'(',zz,')',' = ','Simulink.BusElement',';','n');%写入第一行数据
fprintf(fid, str_tmp);%写入文档
str_tmp = strcat(char(namess),'(',zz,')','.','Name',' = ','"',char(txt1(i,2)),'"',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','Dimensions',' = ','1',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','DataType',' = ','"',char(txt1(i,4)),'"',';','n');
fprintf(fid, str_tmp);
fprintf(fid,'n');
else%这里使用if else语句是因为在没有Bus信号名的情况下,使用的编写文件
z=z+1;%这里的z+1是为了Bus格式中的(1)(2)
zz=char(z);%文本
namess=strcat(names,'_signal');%这里主要是区分bus格式的头和BUS名
str_tmp = strcat(char(namess),'(',zz,')',' = ','Simulink.BusElement',';','n');%写入文本
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','Name',' = ','"',char(txt1(i,2)),'"',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','Dimensions',' = ','1',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','DataType',' = ','"',char(txt1(i,4)),'"',';','n');
fprintf(fid, str_tmp);
fprintf(fid,'n');
fprintf(fid,'n');
这部分主要是添加最后的bus名称
因为所有的名称都是在元素后边的,有的时候一个bus 我们也不知道有多少个元素,所以不知道什么时候编写上图的话,这个时候只能通过判断下一行的数据中有没有新的bus名出现,如果有,就待变这个bus的元素已经写完,可以写入这个函数,但是这里会出现一个问题,就是当最后一个函数写完后,已经没有下一行数据了,这个时候读取下一行数据就会报错,所以这里先判断了是不是最后一个,如果是最后一行,那我们就不写上图的函数看,最后在循环语句结束后补一个就可以了
if (strcmp(char(i),char(inportLength1)))
%这里是防止最后一位i的值超出循环语句报错
%如果满足循环语句最后一位,那么我们认为所有的BUS已经完成脚本编写,处理最后一个bus'信号没有完成
%AAA=Simulink.Bus;
%AAA.Elements=AAA_signal;
%这个语句
else
if (strcmp(char(yyy(i+1,1)),'true'))
%这里是需要判断什么时候添加,
%AAA=Simulink.Bus;
%AAA.Elements=AAA_signal;
%因为不清楚BUS信号有几个元素,所以只能用下一个的bus名是否刷新来判断是否添加上边的语句
str_tmp = strcat(char(names),'=','Simulink.Bus;','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(names),'.Elements=',char(namess),';','n');
fprintf(fid, str_tmp);
end
end
end
这里就是补最后一个bus名称
str_tmp = strcat(char(names),'=','Simulink.Bus;','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(names),'.Elements=',char(namess),';','n');
fprintf(fid, str_tmp);
%这里是因为之前的判断没有编写脚本随后一个bus的
%AAA=Simulink.Bus;
%AAA.Elements=AAA_signal;
%这里需要完成最后一个的添加
这里是将Workspace数据导入到数据字典,也要写新的脚本中,最后调用函数,调用函数前,需要清理之前代码生成的其他数据,避免将其他数据混入数据字典中
str_tmp = strcat('importFromBaseWorkspace(Simulink.data.dictionary.open("',ccc,'"));','n');
%这句话是将Workspace数据导入到数据字典
fprintf(fid, str_tmp);
fprintf(fid,'n');
str_tmp = strcat('clc; clear;','n');
fprintf(fid, str_tmp);
fprintf(fid,'n');
clc; clear;
demoVar();
最后我们数据字典中的数据就做好啦
表格模板脚本
关于上边我写的表格模板,这里也做了个脚本,由于过于简单,就直接放在这里用吧
xlswrite('demo.xlsx',{'SignalName'},'Signal','A1');
xlswrite('demo.xlsx',{'DataType'},'Signal','B1');
xlswrite('demo.xlsx',{'Dimensions'},'Signal','C1');
xlswrite('demo.xlsx',{'Initia ValueStorageClass'},'Signal','D1');
xlswrite('demo.xlsx',{'CustomStorageClass'},'Signal','E1');
xlswrite('demo.xlsx',{'HeaderFile'},'Signal','F1');
xlswrite('demo.xlsx',{'Description'},'Signal','G1');
xlswrite('demo.xlsx',{'备注'},'Signal','H1');
xlswrite('demo.xlsx',{'BusName'},'BUS','A1');
xlswrite('demo.xlsx',{'BusElementName'},'BUS','B1');
xlswrite('demo.xlsx',{'Dimensions'},'BUS','C1');
xlswrite('demo.xlsx',{'DataType'},'BUS','D1');
整理后的代码
%yr:2022.12.14
[filetxt,pathtxt] = uigetfile('*.*','Please select an image');%文件筐,选择文件
if(filetxt)
filetxt = strcat(pathtxt,filetxt);
filetxt = lower(filetxt);%一致的小写字母形式
else
msgbox('Please select an image');
return; %退出程序
end
[data,txt]=xlsread(filetxt,'signal');%读取表格内容
A=~cellfun(@isempty,txt);%读取的内容按照0和1辨认
C = readmatrix(filetxt);%获取选择文件的数值信息
name=strsplit(filetxt,'');%将读取的路径分割,这一步是为了找到打开文件的名称
fine=name(length(name));%求长度,为了选取数组最后一个数据
aaa=strsplit(string(fine),'.');%获取文件名称,同时去掉后缀
fined=aaa(1);
Excelname = fined; %获取表格名称
ccc=append(fined,'.sldd');%创建.sldd的名称
inportLength=sum(A(:,2));%求A列的长度
dictionaryObj1 = Simulink.data.dictionary.create(ccc); %创建一个数据字典
for i=2:inportLength%循环语句
Signal_test = Simulink.Signal;
Signal_test.DataType = string(txt(i,2)); %类型
Signal_test.InitialValue = string(C(i-1,4)); %初始值
Signal_test.StorageClass = string(txt(i,5)); %存储方式
Signal_test.Dimensions = C(i-1,3); %维度
dictionaryObj= Simulink.data.dictionary.open(ccc);%打开数据字典
sectionObj = getSection(dictionaryObj,'Design Data');%存入数据
addEntry(sectionObj,string(txt(i,1)),Signal_test);%加入信号
end
%bus相关数据导入
[data1,txt1]=xlsread(filetxt,'Bus');%读取表中BUS页的信号
B=~cellfun(@isempty,txt1);%读取01值
inportLength1=sum(B(:,2));%读取长度
Excel_name = Excelname; %获取表格名称
disp(Excel_name);%创建
mfile_name = strcat(Excel_name,'Var.m'); %编写要创建的脚本文件名:
% 这一步是因为BUS的格式不能通过函数嵌入修改,只能通过创建脚本的方式在运行脚本实现BUS导入数据字典
fid = fopen(mfile_name,'w');%打开文件
fprintf(fid,'n');%文件中空格
l=1;
yyy = string(B(:,1));%求取1列的输入查看有效值,作为后边的判断bus名称使用
for i=2:inportLength1%循环语句
global names;%这里需要定义一个全局变量,为主要是下边的if else使用
if (strcmp(char(yyy(i,1)),'true'))%判断yyy的数值是不是有值情况
names=txt1(i,1);%上传一个全局变量名称,为了后边的BUS格式使用
namess=strcat(names,'_signal');%这里主要是区分bus格式的头和BUS名
z=49;%这里通过ascii码转为1
zz=char(z);%转文本
str_tmp = strcat(char(namess),'(',zz,')',' = ','Simulink.BusElement',';','n');%写入第一行数据
fprintf(fid, str_tmp);%写入文档
str_tmp = strcat(char(namess),'(',zz,')','.','Name',' = ','"',char(txt1(i,2)),'"',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','Dimensions',' = ','1',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','DataType',' = ','"',char(txt1(i,4)),'"',';','n');
fprintf(fid, str_tmp);
fprintf(fid,'n');
else%这里使用if else语句是因为在没有Bus信号名的情况下,使用的编写文件
z=z+1;%这里的z+1是为了Bus格式中的(1)(2)
zz=char(z);%文本
namess=strcat(names,'_signal');%这里主要是区分bus格式的头和BUS名
str_tmp = strcat(char(namess),'(',zz,')',' = ','Simulink.BusElement',';','n');%写入文本
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','Name',' = ','"',char(txt1(i,2)),'"',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','Dimensions',' = ','1',';','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(namess),'(',zz,')','.','DataType',' = ','"',char(txt1(i,4)),'"',';','n');
fprintf(fid, str_tmp);
fprintf(fid,'n');
fprintf(fid,'n');
if (strcmp(char(i),char(inportLength1)))
%这里是防止最后一位i的值超出循环语句报错
%如果满足循环语句最后一位,那么我们认为所有的BUS已经完成脚本编写,处理最后一个bus'信号没有完成
%AAA=Simulink.Bus;
%AAA.Elements=AAA_signal;
%这个语句
else
if (strcmp(char(yyy(i+1,1)),'true'))
%这里是需要判断什么时候添加,
%AAA=Simulink.Bus;
%AAA.Elements=AAA_signal;
%因为不清楚BUS信号有几个元素,所以只能用下一个的bus名是否刷新来判断是否添加上边的语句
str_tmp = strcat(char(names),'=','Simulink.Bus;','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(names),'.Elements=',char(namess),';','n');
fprintf(fid, str_tmp);
end
end
end
fprintf(fid,'n');
end
str_tmp = strcat(char(names),'=','Simulink.Bus;','n');
fprintf(fid, str_tmp);
str_tmp = strcat(char(names),'.Elements=',char(namess),';','n');
fprintf(fid, str_tmp);
%这里是因为之前的判断没有编写脚本随后一个bus的
%AAA=Simulink.Bus;
%AAA.Elements=AAA_signal;
%这里需要完成最后一个的添加
fprintf(fid,'n');
fprintf(fid,'n');
str_tmp = strcat('importFromBaseWorkspace(Simulink.data.dictionary.open("',ccc,'"));','n');
%这句话是将Workspace数据导入到数据字典
fprintf(fid, str_tmp);
fprintf(fid,'n');
str_tmp = strcat('clc; clear;','n');
fprintf(fid, str_tmp);
fprintf(fid,'n');
clc; clear;
demoVar();
后续
我会更新枚举导入,由于最近工作要忙别的,暂时先去搬砖,等到我的后续更新。
最后
以上就是清秀电源为你收集整理的【matlab专题】脚本(4):Excel数据导入数据字典:Bus、Signal、Enum前言思路分析脚本表格模板脚本整理后的代码后续的全部内容,希望文章能够帮你解决【matlab专题】脚本(4):Excel数据导入数据字典:Bus、Signal、Enum前言思路分析脚本表格模板脚本整理后的代码后续所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复