[西门子] 干货分享:使用博图SCL编程实现可自由选择年、月、日、...

[复制链接]
查看74780 | 回复0 | 2024-4-15 08:39:42 | 显示全部楼层 |阅读模式
之前我们分享了如何实现将DTL格式的日期时间转换为字符串,可直接封装成FC块供重复使用。

本次程序以实际生产中维护保养模块需求,实现维护保养自动生成结束时间,及当前设备保养状态,周期可根据需求自由选择按年、月、日、时、分自由选择;可直接应用于上位机、触摸屏等,HMI实现效果如下图:


image-20240401171347174
实现步骤

Step1:将当前时间实时转为string格式(已封装标准FC可重复使用)
REGION 将当前时间DTL实时转化为String
    "C602_DateTime_DTL_To_String"(DateTime_DTL := #DateTime_Now_DTL,
                                  DateTime_String => #DateTime_Now_String);
END_REGION

Step2:当模式不=0时,为开始时间和结束时间赋初值
REGION 当模式不=0时,为开始时间和结束时间赋初值;
   
    IF #SelectMode <> 0 THEN
        // 初始化,通过初始化状态ONS[0]判断;
        IF #ONS[0] = FALSE THEN
            // 将当前时间Move给维护开始时间(开始时间只有在维护确认后,才可以重新赋值)
            #Start_DateTime := #DateTime_Now_String;
            #Start_DateTime_DTL := #DateTime_Now_DTL;
            // 初始化完成
            #ONS[0] := TRUE;
        END_IF;
    ELSE
        // 当SelectMode==0时,开始时间,输出时间都为空; 此处用空格代替;
        #Start_DateTime := ' ';
        #End_DateTime := ' ';
        #ONS[0] := FALSE;
    END_IF;
END_REGION

Step3:根据选择模式,计算直接累加后的结束时间
REGION 根据选择模式,计算直接累加后的结束时间
    CASE #SelectMode OF
        1:
            #End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR + #DataSet;
            #End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
            #End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
            #End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
            #End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
            #End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
           
        2:
            #End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
            #End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH + #DataSet;
            #End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
            #End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
            #End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
            #End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
        3:
            #End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
            #End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
            #End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY + #DataSet;
            #End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
            #End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
            #End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
        4:
            #End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
            #End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
            #End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
            #End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR + #DataSet;
            #End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE;
            #End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
        5:
            #End_DateTime_INT.YEAR := #Start_DateTime_DTL.YEAR;
            #End_DateTime_INT.MONTH := #Start_DateTime_DTL.MONTH;
            #End_DateTime_INT.DAY := #Start_DateTime_DTL.DAY;
            #End_DateTime_INT.HOUR := #Start_DateTime_DTL.HOUR;
            #End_DateTime_INT.MINUTE := #Start_DateTime_DTL.MINUTE + #DataSet;
            #End_DateTime_INT.SECOND := #Start_DateTime_DTL.SECOND;
    END_CASE;
END_REGION

Step4:对累加后的数据进行处理
REGION 对累加后的数据进行处理
    // 判断分钟是否超过60分钟,如果超过则小时+1,分钟数-60
    IF #End_DateTime_INT.MINUTE >= 60 THEN
        #End_DateTime_INT.HOUR := #End_DateTime_INT.HOUR + TRUNC(#End_DateTime_INT.MINUTE / 60);
        #End_DateTime_INT.MINUTE := #End_DateTime_INT.MINUTE - TRUNC(#End_DateTime_INT.MINUTE / 60) * 60;
    END_IF;
   
    // 判断小时是否超过24小时,如果超过则日+1,分钟数-24
    IF #End_DateTime_INT.HOUR >= 24 THEN
        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY + TRUNC(#End_DateTime_INT.HOUR / 24);
        #End_DateTime_INT.HOUR := #End_DateTime_INT.HOUR - TRUNC(#End_DateTime_INT.HOUR / 24) * 24;
    END_IF;
   
   
    WHILE #SelectMode <> 0 DO
        REGION 对“日”进行处理,由于日处理,牵扯到每月多少天,包括2月,润年等,所以需要使用循环处理
            CASE #End_DateTime_INT.MONTH OF
                1:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
                2:
                    IF (#End_DateTime_INT.YEAR - TRUNC(#End_DateTime_INT.YEAR / 4) * 4) = 0 THEN
                        IF #End_DateTime_INT.DAY > 29 THEN
                            #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                            #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 29;
                        END_IF;
                    ELSE
                        IF #End_DateTime_INT.DAY > 28 THEN
                            #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                            #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 28;
                        END_IF;
                    END_IF;
                3:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
                4:
                    IF #End_DateTime_INT.DAY > 30 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
                    END_IF;
                5:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
                6:
                    IF #End_DateTime_INT.DAY > 30 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
                    END_IF;
                7:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
                8:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
                9:
                    IF #End_DateTime_INT.DAY > 30 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
                    END_IF;
                10:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
                11:
                    IF #End_DateTime_INT.DAY > 30 THEN
                        #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH + 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 30;
                    END_IF;
                12:
                    IF #End_DateTime_INT.DAY > 31 THEN
                        #End_DateTime_INT.MONTH := 1;
                        #End_DateTime_INT.DAY := #End_DateTime_INT.DAY - 31;
                    END_IF;
            END_CASE;
        END_REGION
        REGION 对月份进行处理
            IF #End_DateTime_INT.MONTH > 12 THEN
                #End_DateTime_INT.YEAR := #End_DateTime_INT.YEAR + 1;
                #End_DateTime_INT.MONTH := #End_DateTime_INT.MONTH - 12;
            END_IF;
        END_REGION
        REGION 对处理结果进行判断,处理完毕则跳出循环;
            IF #End_DateTime_INT.MONTH = 1
                OR #End_DateTime_INT.MONTH = 3
                OR #End_DateTime_INT.MONTH = 5
                OR #End_DateTime_INT.MONTH = 7
                OR #End_DateTime_INT.MONTH = 8
                OR #End_DateTime_INT.MONTH = 10
                OR #End_DateTime_INT.MONTH = 12 THEN
                IF #End_DateTime_INT.DAY <= 31 THEN
                    EXIT;
                END_IF;
            END_IF;
            IF #End_DateTime_INT.MONTH = 4
                OR #End_DateTime_INT.MONTH = 6
                OR #End_DateTime_INT.MONTH = 9
                OR #End_DateTime_INT.MONTH = 11
                OR #End_DateTime_INT.MONTH = 10
                OR #End_DateTime_INT.MONTH = 12 THEN
                IF #End_DateTime_INT.DAY <= 30 THEN
                    EXIT;
                END_IF;
            END_IF;
            IF #End_DateTime_INT.MONTH = 2 THEN
                IF (#End_DateTime_INT.YEAR - TRUNC(#End_DateTime_INT.YEAR / 4) * 4) = 0 THEN
                    IF #End_DateTime_INT.DAY <= 29 THEN
                        EXIT;
                    END_IF;
                ELSE
                    IF #End_DateTime_INT.DAY <= 28 THEN
                        EXIT;
                    END_IF;
                END_IF;
            END_IF;
        END_REGION
    END_WHILE;
END_REGION

Step5:将处理后的累加值发送Move给结束时间DTL,将结束时间DTL转化为String
REGION 将处理后的累加值发送Move给结束时间DTL,将结束时间DTL转化为String
    #End_DateTime_DTL.YEAR := #End_DateTime_INT.YEAR;
    #End_DateTime_DTL.MONTH := #End_DateTime_INT.MONTH;
    #End_DateTime_DTL.DAY := #End_DateTime_INT.DAY;
    #End_DateTime_DTL.HOUR := #End_DateTime_INT.HOUR;
    #End_DateTime_DTL.MINUTE := #End_DateTime_INT.MINUTE;
    #End_DateTime_DTL.SECOND := #End_DateTime_INT.SECOND;
    IF #SelectMode <> 0 THEN
        "C602_DateTime_DTL_To_String"(DateTime_DTL := #End_DateTime_DTL,
                                      DateTime_String => #End_DateTime);
    ELSE
        #End_DateTime := ' ';
    END_IF;
END_REGION

Step6:比较当前日期时间与结束日期时间,判断当前状态
REGION 判断状态
    IF #SelectMode = 0 THEN
        #Status := 0;
    ELSE
        IF #DateTime_Now_DTL.YEAR > #End_DateTime_DTL.YEAR THEN
            #Status := 2;
        ELSIF #DateTime_Now_DTL.YEAR < #End_DateTime_DTL.YEAR THEN
            #Status := 1;
        ELSIF #DateTime_Now_DTL.YEAR = #End_DateTime_DTL.YEAR THEN
            IF #DateTime_Now_DTL.MONTH > #End_DateTime_DTL.MONTH THEN
                #Status := 2;
            ELSIF #DateTime_Now_DTL.MONTH < #End_DateTime_DTL.MONTH THEN
                #Status := 1;
            ELSIF #DateTime_Now_DTL.MONTH = #End_DateTime_DTL.MONTH THEN
                IF #DateTime_Now_DTL.DAY > #End_DateTime_DTL.DAY THEN
                    #Status := 2;
                ELSIF #DateTime_Now_DTL.DAY < #End_DateTime_DTL.DAY THEN
                    #Status := 1;
                ELSIF #DateTime_Now_DTL.DAY = #End_DateTime_DTL.DAY THEN
                    IF #DateTime_Now_DTL.HOUR > #End_DateTime_DTL.HOUR THEN
                        #Status := 2;
                    ELSIF #DateTime_Now_DTL.HOUR < #End_DateTime_DTL.HOUR THEN
                        #Status := 1;
                    ELSIF #DateTime_Now_DTL.HOUR = #End_DateTime_DTL.HOUR THEN
                        IF #DateTime_Now_DTL.MINUTE > #End_DateTime_DTL.MINUTE THEN
                            #Status := 2;
                        ELSIF #DateTime_Now_DTL.MINUTE < #End_DateTime_DTL.MINUTE THEN
                            #Status := 1;
                        ELSIF #DateTime_Now_DTL.MINUTE = #End_DateTime_DTL.MINUTE THEN
                            IF #DateTime_Now_DTL.SECOND > #End_DateTime_DTL.SECOND THEN
                                #Status := 2;
                            ELSIF #DateTime_Now_DTL.SECOND < #End_DateTime_DTL.SECOND THEN
                                #Status := 1;
                            END_IF;
                        END_IF;
                    END_IF;
                END_IF;
            END_IF;
        END_IF;
    END_IF;
END_REGION
DTL格式日期时间转String



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则