【博图TIA-Api】通过Excel自动新建文件夹和导入FB块
说明
续上一篇文章,这次是根据Excel表格在程序内新建文件夹和导入FB块。
思路
- 调用TIA的Api接口
- 实现方式为C#的"Windows 窗体应用(.NET Framework),(默认PC已经装了Visual Studio)
- 文件夹名和FB块名存在Excel文件中,导入时需要选择文档
- 西门子子接口使用文档(中文的) 点击链接进入
- 注意如果文件夹已经存在就不能新建。
- FB块如果存在可以覆盖,方便快速修改。
准备
该文章已提过的准备事项就不再重复,只提及未重复的。链接: 【博图TIA-Api】通过Excel自动快速导入IO变量
获取Excel表格内文件名和FB块名等信息
上述链接可查看。
新建文件夹部分
筛分获取的文件夹数据,去掉重复内容
注意这里并不是去除程序内的重复文件夹,只是对Excel文件内读取的文件名去重。
csharp
public static void CreatNewFileGroup(string filepath, PlcSoftware plcsoftware, bool enabled)
{
if (!enabled)
{
return;
}
string[] result = new string[300];
int i;
int j = 1;
bool Mid;
string[,] strings = new string[1000, 15];
strings = ManualImport.ManualReadExcelFile(filepath);
//筛选出所有组名
for (i = 1; strings[i, 1] != null; i++)
{
Mid = false;
//有重复的就不加入数组
foreach (string strmid in result)
{
if (strmid == strings[i, 1])
{
Mid = true;
break;
}
}
//没重复的添加进数组
if (!Mid)
{
result[j] = strings[i, 1];
j++;
}
Mid = true;
}
//调用文件夹新建程序
for (i = 1; result[i] != null; i++)
{
ManualImport.CreateBlockGroup(plcsoftware, result[i]);
}
}
创建文件夹
注意由于PLC内文件夹可能会有很多层级,我这里默认是三个层级,如果层级更多可以按照这样写。[]
csharp
public static void CreateBlockGroup(PlcSoftware plcsoftware, string FileName)
{
//测试用
string[] strings = new string[20];
int i, j;
PlcBlockGroup userblock1, userblock2, userblock3, userblock4;
PlcBlockGroup finallyblock;
PlcBlockSystemGroup systemGroup = plcsoftware.BlockGroup;
//测试用于查看块组名字--程序块
#region 已屏蔽
//string NameBlock =systemGroup.Name;
#endregion
//获取程序块下三个大文件夹,第0个是程序块文件夹最下面的一个,也就是需要的
#region 获取 根目录
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in systemGroup.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "根目录名")
{
j = i;
}
i = i + 1;
}
userblock1 = systemGroup.Groups[j];
#endregion
#region 获取 层级一
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock1.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "层级一名")
{
j = i;
}
i = i + 1;
}
userblock2 = userblock1.Groups[j];
#endregion
#region 获取 层级二
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock2.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "层级二名")
{
j = i;
}
i = i + 1;
}
userblock3 = userblock2.Groups[j];
#endregion
#region 获取 层级三
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock3.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "层级三名")
{
j = i;
}
i = i + 1;
}
userblock4 = userblock3.Groups[j];
#endregion
finallyblock = userblock4;
//确保文件夹不重复
j = 0;
foreach (PlcBlockGroup blockgroup in finallyblock.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == FileName)
{
//代表文件夹已经存在
j = 100;
}
i = i + 1;
}
if (j == 100)
{
return;
}
else
{
PlcBlockUserGroupComposition groupComposition = finallyblock.Groups;
//新建文件夹名
PlcBlockUserGroup myCreatedGroup = groupComposition.Create(FileName);
}
}
导入FB块
导出FB块的xml文件
注意一般这个功能适合哪些重复的FB块导入,比如说一些标准块。
导出FB块的xml文件可以从版本控制接口导出。
查找需要放置的文件夹
这里就以之前的三个层级位置举例。
这里需要返回需要的文件夹变量PlcBlockGroup
csharp
public static PlcBlockGroup FindMovementFB(string BlockGroupName, PlcSoftware plcsoftware)
{
string[] strings = new string[20];
int i, j;
PlcBlockGroup userblock1, userblock2, userblock3, userblock4, userblock5;
PlcBlockGroup finallyblock;
PlcBlockSystemGroup systemGroup = plcsoftware.BlockGroup;
//测试用于查看块组名字--程序块
#region 已屏蔽
//string NameBlock =systemGroup.Name;
#endregion
//获取程序块下三个大文件夹,第0个是程序块文件夹最下面的一个,也就是需要的OEM
#region 获取 根目录
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in systemGroup.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "根目录名")
{
j = i;
}
i = i + 1;
}
userblock1 = systemGroup.Groups[j];
#endregion
#region 获取 层级一
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock1.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "层级一名")
{
j = i;
}
i = i + 1;
}
userblock2 = userblock1.Groups[j];
#endregion
#region 获取 层级二
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock2.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "层级二名")
{
j = i;
}
i = i + 1;
}
userblock3 = userblock2.Groups[j];
#endregion
#region 获取 层级三
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock3.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == "层级三名")
{
j = i;
}
i = i + 1;
}
userblock4 = userblock3.Groups[j];
#endregion
i = 0;
j = 0;
foreach (PlcBlockGroup blockgroup in userblock4.Groups)
{
strings[i] = blockgroup.Name;
if (strings[i] == BlockGroupName)
{
j = i;
}
i = i + 1;
if (i >= 30)
{
break;
}
}
userblock5 = userblock4.Groups[j];
#region 获取需要放置的文件夹
#endregion
finallyblock = userblock5;
//返回需要的PlcBlockGroup
return finallyblock;
}
导入块
这里的xml文件默认放在改程序的根目录。
csharp
public static void InputMovementFB(string filepath, string Xmlpath, PlcSoftware plcsoftware, bool enabled)
{
if (!enabled)
{
return;
}
string[] result = new string[300];
int i;
int j = 1;
bool Mid;
string[,] strings = new string[1000, 18];
//读取Excel表格内容
strings = ManualImport.ManualReadExcelFile(filepath);
XmlDocument xmlDoc = new XmlDocument();
//加载xml文件,文件
xmlDoc.Load(Xmlpath);
bool mid1, mid2, mid3;
for (i = 1; strings[i, 1] != null; i++)
{
#region 修改FB块名字
//查找要修改的节点
XmlNode Name = xmlDoc.SelectSingleNode("Document/SW.Blocks.FB/AttributeList");
//取出所有的子节点
XmlNodeList xnl = Name.ChildNodes;
mid1 = false;
mid2 = false;
//取出PLC变量表名字
foreach (XmlNode xmlNode in xnl)
{
//将节点转换一下类型
XmlElement xmlElement = (XmlElement)xmlNode;
//判断该子节点是否是要查找的节点
if (xmlElement.Name == "Name")
{
//设置新值
xmlElement.InnerText = "NO" + strings[i,2]+"MB"+ strings[i,5]+"_"+ strings[i,3];
mid1 = true;
}
//判断该子节点是否是要查找的节点
if (xmlElement.Name == "Number")
{
//设置新值
xmlElement.InnerText = Convert.ToString(600+(Convert.ToInt32(strings[i, 2])-1)*20+Convert.ToInt32(strings[i, 5]));
mid2 = true;
}
if (mid1 && mid2)
{
break;
}
}
#endregion
//保存修改的Xml文件内容
xmlDoc.Save(Xmlpath);
FindMovementFB(strings[i, 1], plcsoftware).Blocks.Import(new FileInfo(Xmlpath), ImportOptions.Override); ;
}
}
注意这里修改的xml文件位置在此处
*[注]: 这里其实可以写成通用的程序,但一般用不到,凑合着用就行。