在php中使用mb_substr($row['title'],0,15,'utf-8')解决获取的字符后面几们的乱码问题

本文介绍在PHP中如何使用mb_substr函数正确截取字符串,避免因编码问题导致的乱码现象。通过统一编码方式确保字符完整显示。

在php中使用mb_substr($row['title'],0,15,'utf-8')解决获取的字符后面几们的乱码问题.

要让自己在php方面有所造就,就得自己写实例,做项目.只有这样才能遇到问题,当我们

把这些问题一个一个解决的时候,也就是我们的技术在一步步成熟了.

今天遇到 的问题还真多,不过都自己解决了.

读取前10条新闻记录,后面几个字符乱码了.因为我们读取的是前15个字符,如果我们的编码不同的话,

就会造成有些记录的某些字符只读取了一半,所以在用这个的时候我们要统一编码.统一了编码后

就不会出现后面时不时有几个字符乱码了.

哈哈,就写到这里吧!就要下班了.

今天做了一个php的新闻发布.感觉php熟悉多了.

# 加载必要的包 library(mgcv) library(readxl) library(rms) library(devEMF) library(broom) library(car) library(ggplot2) library(patchwork) library(viridis) # 设置输出目录 output_dir <- "F:/eddies_data/gam1" # 如果目录不存在,则创建 if (!dir.exists(output_dir)) { dir.create(output_dir, recursive = TRUE) cat("已创建输出目录:", output_dir, "\n") } # 读取数据 data <- read_excel("F:/eddies_data/fishery_eddies1.xlsx") # 查看数据结构 str(data) head(data) # 检查数据中是否有缺失值 cat("数据缺失值统计:\n") print(colSums(is.na(data))) # 创建对数变换后的响应变量 data$log_cpue <- log(data$cpue + 1) # 创建因子变量:正就是反气旋涡,负就是气旋涡 data$eddy_type_fac <- factor(data$eddy_type, levels = c(-1, 1), labels = c("气旋涡", "反气旋涡")) # 查看数据分布 cat("气旋涡数据点数量:", sum(data$eddy_type == -1 & !is.na(data$eddy_type)), "\n") cat("反气旋涡数据点数量:", sum(data$eddy_type == 1 & !is.na(data$eddy_type)), "\n") # 使用交互效应模型 final_model <- gam(log_cpue ~ eddy_type_fac + te(longitude, latitude) + # 经纬度交互项,不区分涡旋类型 s(relative_distance, by = eddy_type_fac) + s(amplitude, by = eddy_type_fac) + s(speed_average, by = eddy_type_fac) + as.factor(year) + # 年份作为固定效应 as.factor(month), # 月份作为固定效应 # 查看模型摘要 cat("\n=== 交互效应模型摘要 ===\n") print(summary(final_model)) # 创建分别显示每个涡旋类型偏效应图的函数,优化纵坐标范围 plot_effect_by_type_optimized <- function(model, variable, eddy_types = c("气旋涡", "反气旋涡")) { # 创建一个新的数据框用于预测 plot_data <- expand.grid( eddy_type_fac = factor(eddy_types, levels = c("气旋涡", "反气旋涡")), stringsAsFactors = FALSE ) # 为每个变量设置合理的范围 if (variable == "longitude") { plot_data[[variable]] <- seq(min(data$longitude, na.rm = TRUE), max(data$longitude, na.rm = TRUE), length = 100) } else if (variable == "latitude") { plot_data[[variable]] <- seq(min(data$latitude, na.rm = TRUE), max(data$latitude, na.rm = TRUE), length = 100) } else if (variable == "relative_distance") { plot_data[[variable]] <- seq(min(data$relative_distance, na.rm = TRUE), max(data$relative_distance, na.rm = TRUE), length = 100) } else if (variable == "amplitude") { plot_data[[variable]] <- seq(min(data$amplitude, na.rm = TRUE), max(data$amplitude, na.rm = TRUE), length = 100) } else if (variable == "speed_average") { plot_data[[variable]] <- seq(min(data$speed_average, na.rm = TRUE), max(data$speed_average, na.rm = TRUE), length = 100) } # 设置其他变量为均值 other_vars <- c("longitude", "latitude", "relative_distance", "amplitude", "speed_average") other_vars <- setdiff(other_vars, variable) for (var in other_vars) { plot_data[[var]] <- mean(data[[var]], na.rm = TRUE) } # 设置年份和月份为最常见的水平 plot_data$year <- as.integer(names(sort(table(data$year), decreasing = TRUE)[1])) plot_data$month <- as.integer(names(sort(table(data$month), decreasing = TRUE)[1])) # 预测 - 使用terms获取偏效应 pred <- predict(model, newdata = plot_data, type = "terms", se.fit = TRUE) # 提取对应变量的偏效应 term_names <- colnames(pred$fit) var_terms <- grep(variable, term_names, value = TRUE) # 为每个eddy_type提取对应的项 plot_data$fit <- NA plot_data$se <- NA for (i in 1:nrow(plot_data)) { eddy_type <- as.character(plot_data$eddy_type_fac[i]) # 查找对应的项名称 target_term <- grep(paste0(variable, ".+", eddy_type), term_names, value = TRUE) if (length(target_term) == 0) { # 如果找不到,尝试其他匹配方式 target_term <- grep(paste0(variable, ".*", substr(eddy_type, 1, 2)), term_names, value = TRUE) } if (length(target_term) > 0) { plot_data$fit[i] <- pred$fit[i, target_term[1]] plot_data$se[i] <- pred$se.fit[i, target_term[1]] } } plot_data$upper <- plot_data$fit + 1.96 * plot_data$se plot_data$lower <- plot_data$fit - 1.96 * plot_data$se # 计算纵坐标的合理范围,让曲线变化更明显 y_range <- range(plot_data$fit, na.rm = TRUE) y_span <- diff(y_range) # 如果变化范围太小,扩大纵坐标范围以显示变化 if (y_span < 0.1) { y_center <- mean(y_range) y_range <- c(y_center - 0.1, y_center + 0.1) } else { # 添加一些边距 y_range <- c(y_range[1] - 0.05 * y_span, y_range[2] + 0.05 * y_span) } # 绘制图表 p <- ggplot(plot_data, aes_string(x = variable, y = "fit", color = "eddy_type_fac", fill = "eddy_type_fac")) + geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.2, color = NA) + geom_line(size = 1) + labs(title = paste0(variable, "对对数CPUE的偏效应"), x = switch(variable, "longitude" = "经度", "latitude" = "纬度", "relative_distance" = "相对距离", "amplitude" = "振幅", "speed_average" = "平均速度", variable), y = "对对数CPUE的影响", color = "涡旋类型", fill = "涡旋类型") + theme_minimal() + theme(legend.position = "bottom") + coord_cartesian(ylim = y_range) # 关键:限制纵坐标范围 return(p) } # 使用更简单但有效的方法 - 直接使用plot.gam但调整纵坐标 plot_smooth_effects <- function(model, data) { # 获取所有平滑项 smooth_terms <- summary(model)$s.table # 为每个变量创建偏效应图 variables <- c("relative_distance", "amplitude", "speed_average") # 移除了经纬度 for (var in variables) { png(file.path(output_dir, paste0("optimized_", var, "_effect.png")), width = 800, height = 600) # 创建预测数据 new_data <- data.frame(eddy_type_fac = factor(rep(c("气旋涡", "反气旋涡"), each = 100))) # 设置变量范围 var_range <- range(data[[var]], na.rm = TRUE) new_data[[var]] <- rep(seq(var_range[1], var_range[2], length = 100), 2) # 设置其他变量为均值 other_vars <- c("longitude", "latitude", "relative_distance", "amplitude", "speed_average") other_vars <- setdiff(other_vars, var) for (v in other_vars) { new_data[[v]] <- mean(data[[v]], na.rm = TRUE) } # 设置年份和月份为最常见的水平 new_data$year <- as.integer(names(sort(table(data$year), decreasing = TRUE)[1])) new_data$month <- as.integer(names(sort(table(data$month), decreasing = TRUE)[1])) # 预测 - 使用terms获取偏效应 pred <- predict(model, newdata = new_data, type = "terms", se.fit = TRUE) # 提取对应变量的偏效应 term_names <- colnames(pred$fit) var_terms <- grep(var, term_names, value = TRUE) # 为每个eddy_type提取对应的项 new_data$fit <- NA new_data$se <- NA for (i in 1:nrow(new_data)) { eddy_type <- as.character(new_data$eddy_type_fac[i]) # 查找对应的项名称 target_term <- grep(paste0(var, ".+", eddy_type), term_names, value = TRUE) if (length(target_term) == 0) { # 如果找不到,尝试其他匹配方式 target_term <- grep(paste0(var, ".*", substr(eddy_type, 1, 2)), term_names, value = TRUE) } if (length(target_term) > 0) { new_data$fit[i] <- pred$fit[i, target_term[1]] new_data$se[i] <- pred$se.fit[i, target_term[1]] } } new_data$upper <- new_data$fit + 1.96 * new_data$se new_data$lower <- new_data$fit - 1.96 * new_data$se # 计算纵坐标范围 - 聚焦于变化部分 y_range <- range(new_data$fit, na.rm = TRUE) y_span <- diff(y_range) # 如果变化太小,扩大范围 if (y_span < 0.5) { y_center <- mean(y_range) y_range <- c(y_center - 0.25, y_center + 0.25) } # 使用ggplot绘制偏效应图 p <- ggplot(new_data, aes_string(x = var, y = "fit", color = "eddy_type_fac", fill = "eddy_type_fac")) + geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.2, color = NA) + geom_line(size = 1) + labs(title = paste0("偏效应: ", switch(var, "longitude" = "经度", "latitude" = "纬度", "relative_distance" = "相对距离", "amplitude" = "振幅", "speed_average" = "平均速度", var)), x = switch(var, "longitude" = "经度", "latitude" = "纬度", "relative_distance" = "相对距离", "amplitude" = "振幅", "speed_average" = "平均速度", var), y = "对对数CPUE的偏效应", color = "涡旋类型", fill = "涡旋类型") + theme_minimal() + theme(legend.position = "bottom") + coord_cartesian(ylim = y_range) # 关键:聚焦于变化部分 print(p) dev.off() } } # 修改后的经纬度交互偏效应图 plot_spatial_partial_effect <- function(model, data) { # 创建经纬度网格 lon_seq <- seq(min(data$longitude, na.rm = TRUE), max(data$longitude, na.rm = TRUE), length = 50) lat_seq <- seq(min(data$latitude, na.rm = TRUE), max(data$latitude, na.rm = TRUE), length = 50) # 创建预测数据 - 不再区分涡旋类型 grid_data <- expand.grid( longitude = lon_seq, latitude = lat_seq ) # 设置其他变量为均值 grid_data$relative_distance <- mean(data$relative_distance, na.rm = TRUE) grid_data$amplitude <- mean(data$amplitude, na.rm = TRUE) grid_data$speed_average <- mean(data$speed_average, na.rm = TRUE) grid_data$year <- as.integer(names(sort(table(data$year), decreasing = TRUE)[1])) grid_data$month <- as.integer(names(sort(table(data$month), decreasing = TRUE)[1])) # 设置涡旋类型为最常见的水平 grid_data$eddy_type_fac <- factor( names(sort(table(data$eddy_type_fac), decreasing = TRUE)[1]), levels = c("气旋涡", "反气旋涡") ) # 预测 - 使用terms获取偏效应 pred <- predict(model, newdata = grid_data, type = "terms", se.fit = TRUE) # 提取经纬度交互项的偏效应 term_names <- colnames(pred$fit) spatial_term <- grep("te\\(longitude,latitude\\)", term_names, value = TRUE) if (length(spatial_term) > 0) { grid_data$partial_effect <- pred$fit[, spatial_term[1]] # 绘制偏效应图 p <- ggplot(grid_data, aes(x = longitude, y = latitude, fill = partial_effect)) + geom_tile() + scale_fill_viridis_c(name = "偏效应") + labs(title = "经纬度交互项对对数CPUE的偏效应", x = "经度", y = "纬度") + theme_minimal() + theme(legend.position = "bottom") ggsave(file.path(output_dir, "spatial_partial_effect.png"), p, width = 10, height = 8) return(p) } else { cat("警告:未找到经纬度交互项\n") return(NULL) } } # 使用第二种方法绘制优化后的偏效应图 plot_smooth_effects(final_model, data[!is.na(data$eddy_type), ]) # 绘制经纬度交互偏效应图 plot_spatial_partial_effect(final_model, data[!is.na(data$eddy_type), ]) # 创建组合对比图 create_comparison_plots <- function(model, data) { combined_data <- data[!is.na(data$eddy_type), ] # 相对距离对比 p1 <- ggplot(combined_data, aes(x = relative_distance, y = log_cpue, color = eddy_type_fac)) + geom_point(alpha = 0.2) + geom_smooth(method = "gam", formula = y ~ s(x)) + labs(title = "相对距离 vs 对数CPUE", x = "相对距离", y = "对数CPUE") + theme_minimal() + theme(legend.position = "none") # 振幅对比 p2 <- ggplot(combined_data, aes(x = amplitude, y = log_cpue, color = eddy_type_fac)) + geom_point(alpha = 0.2) + geom_smooth(method = "gam", formula = y ~ s(x)) + labs(title = "振幅 vs 对数CPUE", x = "振幅", y = "对数CPUE") + theme_minimal() + theme(legend.position = "none") # 速度对比 p3 <- ggplot(combined_data, aes(x = speed_average, y = log_cpue, color = eddy_type_fac)) + geom_point(alpha = 0.2) + geom_smooth(method = "gam", formula = y ~ s(x)) + labs(title = "平均速度 vs 对数CPUE", x = "平均速度", y = "对数CPUE") + theme_minimal() + theme(legend.position = "none") # 获取图例 legend_plot <- ggplot(combined_data, aes(x = relative_distance, y = log_cpue, color = eddy_type_fac)) + geom_point(alpha = 0.2) + geom_smooth(method = "gam", formula = y ~ s(x)) + labs(color = "涡旋类型") + theme_minimal() + theme(legend.position = "bottom") legend <- cowplot::get_legend(legend_plot) # 组合图表 top_row <- p1 + p2 bottom_row <- p3 + plot_spacer() # 占位符保持对齐 combined <- top_row / bottom_row / legend + plot_layout(heights = c(2, 2, 0.5)) ggsave(file.path(output_dir, "comparison_scatter_plots.png"), combined, width = 12, height = 10) } # 创建对比散点图 create_comparison_plots(final_model, data) # 模型诊断 cat("\n=== 模型诊断 ===\n") png(file.path(output_dir, "model_diagnostics.png"), width = 800, height = 600) par(mfrow = c(2, 2)) gam.check(final_model) dev.off() # 保存模型结果 sink(file.path(output_dir, "model_summary.txt")) cat("GAM模型分析结果\n") cat("===============\n\n") print(summary(final_model)) sink() cat("\n分析完成!优化后的图表已保存到:", output_dir, "\n") 帮我分析一下这个代码正确吗
最新发布
11-14
#!/usr/bin/perl -w ##########################程式信息########################## #脚本名称:防焊开窗优化程式(solder_dfm.pl) #开发人员:欣强电子电脑室(唐伟) #开发时间:2017年81日 #版本信息:Ver_A.1.0 (A:制前规则变更,外部变更或升级;1.0:脚本基带版本号,内部变更或升级) #修改信息:当前版本(Ver_A.1.0),首次开发测试,暂无版本变更信息 ##########################程式信息########################## ##########################提示代码########################## my $panel_bp_101 = "错误代码:101,当前用户没有执行权限,请联系系统管理员!"; my $panel_bp_102 = "错误代码:102,请打开料号后再执行程式!"; my $panel_bp_103 = "错误代码:103,请在打开Step再执行程式!"; my $panel_bp_104 = "错误代码:104,参数不可有空数值!"; my $panel_bp_105 = "错误代码:105,请选择当前料号的工作层!"; my $panel_bp_106 = "错误代码:106,请选择对比料号的对比层!"; my $panel_bp_107 = "错误代码:107,对比料号Step没有创建profile,无法执行profile范围比对!"; my $panel_bp_108 = "错误代码:108,脚本注册失败,无法获取系统管理员权限!"; ##########################提示代码########################## #库及包的调取 use lib "$ENV{GENESIS_DIR}/$ENV{GENESIS_EDIR}/all/perl"; use Genesis; use Tk; use Tk::Tree; use Tk::PNG; use Tk::Bitmap; use Tk::LabFrame; use Tk::LabEntry; use strict; use Encode; use encoding 'utf-8'; use Date::Calc qw(Delta_Days); use POSIX qw(strftime); use warnings; use Time::Piece; use Date::Calc qw(Delta_Days); require 'shellwords.pl'; ##########################初始化########################## my $f = new Genesis; #new my $version = 'A.1.0(测试版)'; #定义版本号 #获取系统时间 my $date = strftime("%Y年%m月%d日",localtime()); #日期(年--日) my $time = strftime("%H时%M分%S秒", localtime(time)); #时间(时--秒) #获取当前系统,主机名,用户组,用户名 my $Sys_name = &GetUserSymtem(); #系统名 my $Hostname = $ENV{HOST}; #主机名 my $User_group = &GetUserGroup(); #用户组 my $Username = &GetUserName(); #用户名 my $User_prive = &GetUserPrive(); #用户权限 #获取当前工作软件环境(默认获取Incam环境变量) my $Soft_path = $ENV{INCAM_PRODUCT}; #获取当前工作料号及step my $JOB = $ENV{JOB}; #料号 my $STEP = $ENV{STEP}; #Step ##########################初始化########################## #tk界面 my $mw = MainWindow->new(-background => "#CDD2E4"); my ($lVer,$Font,$ImgPath); $ImgPath = "$ENV{GENESIS_DIR}/sys/scripts/solder/icon"; chomp($ImgPath); if ($Sys_name =~ /Win/) { #系统权限 $lVer = "Windows"; $Font = "楷体 10"; } elsif ($Sys_name =~ /Linux/) { #获取系统名 $lVer = `cat /etc/issue | head -n 1`; chomp($lVer); $Font = "Ukai 10"; } else { $lVer = "Other OS"; $Font = "SimSun 10"; } if ($User_prive <= 10) { $mw->withdraw; &MessageDialogWarn("$panel_bp_101"); exit(0); } unless ($JOB) { #料号下执行权限 $mw->withdraw; &MessageDialogWarn("$panel_bp_102"); exit(0); } unless ($STEP) { #料号Step下执行权限 $mw->withdraw; &MessageDialogWarn("$panel_bp_103"); exit(0); } ##########################权限控制######################### #######################定义全局变量######################### my $Job_Path; #获取料号路径 if (defined $Soft_path) { $Job_Path = $f->COM("get_job_path,job=$JOB"); #InCAM } else { $Job_Path = `$ENV{GENESIS_DIR}/e$ENV{GENESIS_VER}/misc/dbutil path jobs $JOB`;chomp $Job_Path; #Genesis2000 } my $next_code = "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsSAAALEgHS3X78AAAANklEQVQokWNgGAjwn4GBwZpUDSRp+s9Aoqb/DHg0MeLQgA7g6piIsNGGFCeR5AeSQomkeMALAJpZEs3h4b2/AAAAAElFTkSuQmCC"; my $Week = localtime->week; # my $images_path = "$ImgPath/icon"; # my ($tmopt,$gxopt,$Smdopt,$lbcyjz) = (1,2,2,2); #初始参数 my ($tmopt,$gxopt,$Smdopt,$lbcyjz) = (0.2,2,2.5,2); #初始参数 my $do_type = 'type_auto1'; my $l_message = undef; my $message = ""; my $mess = ""; my $event_id = undef; my ($Smd_opt_ftsz,$Cov_opt_ftsz,$Suf_opt_ftsz,$Suf_opt_yjsz,$jdzs,$jdzsjdz); #######################定义全局变量######################### ##########################料号数据######################### $f->DO_INFO("-t MATRIX -d ROW -e $JOB/matrix"); my ($info_ref,@maska,@signa,@mask,@sign); for (my $i = 0 ; $i < @{$f->{doinfo}{gROWname}} ; $i++) { $info_ref = { name => @{$f->{doinfo}{gROWname}}[$i], layer_type => @{$f->{doinfo}{gROWlayer_type}}[$i], context => @{$f->{doinfo}{gROWcontext}}[$i], polarity => @{$f->{doinfo}{gROWpolarity}}[$i], side => @{$f->{doinfo}{gROWside}}[$i], }; if ($info_ref->{context} eq "board" && $info_ref->{layer_type} eq "solder_mask" ) { push(@maska,$info_ref->{name}); } elsif ($info_ref->{context} eq "board" && $info_ref->{layer_type} eq "signal" && ($info_ref->{side} eq "top" || $info_ref->{side} eq "bottom")) { push(@signa,$info_ref->{name}); } } ##########################料号数据######################### ##################### #主窗口设置 my $logo1 = $mw->Photo(-format => 'png',-file => "$ImgPath/twei_logo.png"); my $logo2 = $mw->Photo(-format => 'png',-file => "$ImgPath/solder_dfm.png"); my $logo3 = $mw->Photo(-format => 'png',-file => "$ImgPath/ncc.png"); my $gwidth = 635; my $gheight = 350; if ($Sys_name =~ /Linux/) { $gheight = 380; } my $px = int(($mw->screenwidth() - $gwidth) / 2); my $py = int(($mw->screenheight() - $gheight - 20) / 2); $mw->geometry("${gwidth}x${gheight}+$px+$py"); $mw->resizable(0,0); $mw->bind("Escape", sub{exit}); $mw->title("防焊墓碑优化程式(开源免费无限制)"." 版本:$version --BpSystem"); # $mw->iconbitmap("$ImgPath/ncc.ico"); if ($Sys_name =~ /Linux/) { $mw->iconimage($logo3); } else { $mw->iconbitmap("$ImgPath/ncc.ico"); } my $LabelFrame = $mw->Frame( -relief => 'ridge', -background => "#CDD2E4", ) ->pack(-fill => 'x'); my $LabelLogo1 = $LabelFrame->Label( -image => $logo1, -anchor => 'w', -bg => "#CDD2E4", )->pack(-side => "left",-expand => 1); my $LabelText2 = $LabelFrame->Label( -text => " 开源时间:2019-12-17\n开发人员:一阵寒风\n微信号码:358143105", -bg => "#CDD2E4", -font => $Font, -fg => "#2f4f4f")->pack(-side => "left",-expand => 1); my $LabelLogo3 = $LabelFrame->Label( -image => $logo2, -anchor => 'w', -bg => "#CDD2E4" )->pack(-side => "left",-expand => 1); my $msgbar = $mw->Label( -borderwidth => 2, -relief => 'ridge', -bg => "#CDD2E4" )->pack(-side => 'top', -fill => 'x'); my $messbs = " 当前主机:$Hostname 用户组:$User_group 用户名:$Username 用户权限:$User_prive "; my $event_idmse = undef; $msgbar->Label( -textvariable => \$messbs, -font=>$Font, -bg => "#CDD2E4" )->pack(-fill => 'x'); $event_idmse = $mw->repeat(300, \&scroll); my $FrameMain = $mw->LabFrame( -label=>'参数调整区:', -foreground => "red", -font => $Font, -borderwidth => 2, -relief => 'ridge', -background => "#CDD2E4", ) ->pack(-fill => 'both'); my $SubFrameMain = $FrameMain->Frame(-background => "#CDD2E4",) ->pack(-fill => 'both'); ###################################################################################### my $SubFrameL = $SubFrameMain->LabFrame( -label=>'运行级别:', -foreground => "red", -font => $Font, -borderwidth => 2, -relief => 'ridge', -background => "#CDD2E4", ) ->pack(-fill => 'both'); my $main = $SubFrameL->Frame(-bg => "#CDD2E4",)->pack(-side => "top",-fill => 'both',-expand => 1); my $optionFrame = $main->Frame(-bg => "#CDD2E4",)->pack(-fill => 'both',-expand => 1); my $sle = $optionFrame->Radiobutton( -background => "#CDD2E4", -text => "整板制作", -font => $Font, -value => 'type_auto1', -variable => \$do_type, )->pack(-side=>'left',-expand => 1); my $i = 0; while ($i < scalar(@maska)) { $f->INFO(entity_type => 'layer',entity_path => "$JOB/$STEP/$maska[$i]"); if ($f->{doinfo}{gSIDE} eq "top") { my $sle1 = $optionFrame->Radiobutton( -background => "#CDD2E4", -text => "顶层制作", -font => $Font, -value => 'type_auto2', -variable => \$do_type, )->pack(-side=>'left',-expand => 1); my $sle2 = $optionFrame->Radiobutton( -background => "#CDD2E4", -text => "顶层自选", -font => $Font, -value => 'type_auto3', -variable => \$do_type, )->pack(-side=>'left',-expand => 1); } else { my $sle1 = $optionFrame->Radiobutton( -background => "#CDD2E4", -text => "底层制作", -font => $Font, -value => 'type_auto4', -variable => \$do_type, )->pack(-side=>'left',-expand => 1); my $sle2 = $optionFrame->Radiobutton( -background => "#CDD2E4", -text => "底层自选", -font => $Font, -value => 'type_auto5', -variable => \$do_type, )->pack(-side=>'left',-expand => 1); } $i++ } my $select_frm = $SubFrameMain->LabFrame( -label =>"参数设置:单位(mil),均为单边数值,自行调整最优的参数,\"()\"内为推荐参数范围", -borderwidth => 2, -background => "#CDD2E4", -fg => "red", -relief => 'ridge', -font => $Font, )->pack(-side=>'top',-fill=>'both'); my $show_check = $select_frm->Frame( -background => "#CDD2E4", -borderwidth =>2, -height => 20, )->pack(-side=>'top',-fill=>'both'); my $thick_board = $show_check->LabEntry( -label => '铜面SMD开窗值(0/1.0):', -labelBackground => '#CDD2E4', -labelFont => $Font, -textvariable => \$tmopt, -bg => 'white', -width => 15, -relief=>'ridge', -state=>"normal", -labelPack => [qw/-side left -anchor w/], )-> grid(-row => '0', -column => '0'); my $update = $show_check->LabEntry( -label => 'SMD最小盖线值(0/2.0):', -labelBackground => '#CDD2E4', -labelFont => $Font, -textvariable => \$gxopt, -bg => 'white', -width => 15, -relief=>'ridge', -state=>"normal", -labelPack => [qw/-side left -anchor w/], )-> grid(-row => '1', -column => '0'); my $updated = $show_check->Label(-text => ' ',-bg =>'#CDD2E4')->grid(-row => '0', -column => '1'); my $updatee = $show_check->Label(-text => ' ',-bg =>'#CDD2E4')->grid(-row => '1', -column => '1'); my $updats = $show_check->LabEntry( -label => '标准SMD开窗值(2/3.0):', -labelBackground => '#CDD2E4', -labelFont => $Font, -textvariable => \$Smdopt, -bg => 'white', -width => 15, -relief=>'ridge', -state=>"normal", -labelPack => [qw/-side left -anchor w/], )-> grid(-row => '0', -column => '2'); my $updath = $show_check->LabEntry( -label => 'SMD接铜圆角值(0/2.0):', -labelBackground => '#CDD2E4', -labelFont => $Font, -textvariable => \$lbcyjz, -bg => 'white', -width => 15, -relief=>'ridge', -state=>"normal", -labelPack => [qw/-side left -anchor w/], )-> grid(-row => '1', -column => '2'); my $button_frm = $mw->Frame(-background => "#CDD2E4",-borderwidth =>10,-height => 20)->pack(-anchor=>'e',-fill=>'both'); my $create_button = $button_frm->Button( -text => '执行', -command => sub {&appy}, -width => 8, -bg=>'#A1AEE1', -font=> $Font, -height=> 1, )->pack(-side=>'left',-expand => 1,); my $exit_button = $button_frm->Button( -text => '取消', -command => sub {exit;}, -width => 8, -bg=>'#A1AEE1', -font=> $Font, -height=> 1, )->pack(-side=>'left',-expand => 1,); my $help_button = $button_frm->Button( -text => '帮助', -command => \&helps, -width => 8, -bg=>'#A1AEE1', -font=> $Font, -height=> 1, )->pack(-side=>'left',-expand => 1,); ###################################################################################### my $msgarea = $mw->Label(-borderwidth => 2, -relief => 'ridge',-bg => "#7B7E89",-font=>$Font)->pack(-side => 'bottom', -fill => 'x'); my $next = $mw->Photo(-data=>$next_code, -format=>'png'); $msgarea->Label(-image=>$next,-bg => "white")->pack(-side=>'left',-expand => 1); $msgarea->Label(-textvariable => \$mess,-font=>$Font,-bg => "#7B7E89",-fg => "white")->pack(-side =>'left',-expand => 1); $event_id = $mw->repeat(300, \&timeout); MainLoop; #主程序 sub appy { if (scalar(@maska) == 2) { if ($do_type eq 'type_auto1') { @mask = @maska; @sign = @signa; } elsif ($do_type eq 'type_auto2' or $do_type eq 'type_auto3') { @mask = ($maska[0]); @sign = ($signa[0]); } elsif ($do_type eq 'type_auto4' or $do_type eq 'type_auto5') { @mask = ($maska[1]); @sign = ($signa[1]); } } elsif (scalar(@maska) == 1) { if ($do_type eq 'type_auto1') { @mask = @maska; $f->INFO(entity_type => 'layer',entity_path => "$JOB/$STEP/$maska[0]"); my $cjx = $f->{doinfo}{gSIDE}; foreach my $a(@signa) { $f->INFO(entity_type => 'layer',entity_path => "$JOB/$STEP/$a"); if ($f->{doinfo}{gSIDE} eq $cjx) { @sign = ($a); } } } elsif ($do_type eq 'type_auto2' or $do_type eq 'type_auto3') { @mask = @maska; foreach my $b(@signa) { $f->INFO(entity_type => 'layer',entity_path => "$JOB/$STEP/$b"); if ($f->{doinfo}{gSIDE} eq "top") { @sign = ($b); } } } elsif ($do_type eq 'type_auto4' or $do_type eq 'type_auto5') { @mask = @maska; foreach my $c(@signa) { $f->INFO(entity_type => 'layer',entity_path => "$JOB/$STEP/$c"); if ($f->{doinfo}{gSIDE} eq "bottom") { @sign = ($c); } } } } if ($tmopt eq "" || $gxopt eq "" || $Smdopt eq "" || $lbcyjz eq "") { &MessageDialogWarn("$panel_bp_104"); return; } $mw->iconify; $Smd_opt_ftsz = $Smdopt*2 + 1.2; $Cov_opt_ftsz = $gxopt*2 + 0.15; $Suf_opt_ftsz = $tmopt*2 - 0.1; $Suf_opt_yjsz = $tmopt*1; $f->COM ("units,type=inch"); my $a = 0; while ($a < scalar(@mask)) { &ClearLayer(); $f->VOF; &WorkLayer("$mask[$a].bk"); $f->COM ("sel_delete"); $f->VON; &DelectLay( "$mask[$a].tmp", "$mask[$a].tmps", "$mask[$a].tmpp", "$mask[$a].tmppt", "$mask[$a].tmppd", "$mask[$a].tmpos", "$mask[$a].ds", "$mask[$a].tmppp", "$mask[$a].tmpppd", "$mask[$a].tmppp+++", "$mask[$a].smd", "$mask[$a].smds" ); &WorkLayer("$mask[$a]"); &CopyLay("$mask[$a].bk","no",0); &WorkLayer("$sign[$a]"); my $selcct_fe; if ($do_type eq 'type_auto1' or $do_type eq 'type_auto2' or $do_type eq 'type_auto4') { $selcct_fe = &SelAttCopy(".smd",0,0); } elsif ($do_type eq 'type_auto3' or $do_type eq 'type_auto5') { &do_arec; last; } if ($selcct_fe != 0){ &CopyLay("$mask[$a].tmp","no",0); &WorkLayer("$mask[$a].tmp"); &CopyLay("$mask[$a].tmpp","no",0); &CopyLay("$mask[$a].smd","no",0); } else { last; } &WorkLayer("$sign[$a]"); &CopyLay("$mask[$a].tmppp","no",0); &WorkLayer("$mask[$a].tmpp"); if ($tmopt <= 0) { $jdzs = ($tmopt + $gxopt) * 2; $jdzsjdz = abs($jdzs); } else { $jdzs = 0.1; $jdzsjdz = 0; } &CopyLay("$mask[$a].tmppp","yes",$jdzs); &WorkLayer("$mask[$a].tmppp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=$Cov_opt_ftsz,corner_ctl=no"); &WorkLayer("$mask[$a].tmpp"); &CopyLay("$mask[$a].tmppp","yes",$Suf_opt_ftsz); &WorkLayer("$mask[$a].tmppp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=-1.5,corner_ctl=no"); &CopyLay("$mask[$a].tmpppd","no",0); $f->COM ("sel_surf2outline,width=1.5"); &WorkLayer("$mask[$a].tmpppd"); &CopyLay("$mask[$a].tmppp","no",0); &WorkLayer("$mask[$a].tmpp"); $f->COM ("sel_resize,size=$Smd_opt_ftsz,corner_ctl=no"); &CopyLay("$mask[$a].tmppt","no",0); &WorkLayer("$mask[$a].tmppp"); &CopyLay("$mask[$a].tmpp","yes",0); &CopyLay("$mask[$a].tmppt","yes",10); &WorkLayer("$mask[$a].tmppt"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &CopyLay("$mask[$a].tmpp","no",0); &WorkLayer("$mask[$a].tmpp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=-$lbcyjz,corner_ctl=no"); &CopyLay("$mask[$a].tmppd","no",0); $f->COM ("sel_surf2outline,width=$lbcyjz"); &WorkLayer("$mask[$a].tmppd"); &CopyLay("$mask[$a].tmpp","no",0); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &WorkLayer("$mask[$a].tmpp"); $f->COM ("fill_params,type=solid,origin_type=datum,solid_type=fill,std_type=line,min_brush=2,use_arcs=yes,symbol=,dx=0.1,dy=0.1,std_angle=45,std_line_width=10,std_step_dist=50,std_indent=odd,break_partial=yes,cut_prims=no,outline_draw=no,outline_width=0,outline_invert=no"); $f->COM ("sel_fill"); $f->COM ("sel_contourize,accuracy=0.1,break_to_islands=yes,clean_hole_size=3,clean_hole_mode=x_and_y"); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_resize,size=-0.5,corner_ctl=no"); &WorkLayer("$mask[$a].tmpp"); $f->COM ("sel_ref_feat,layers=$mask[$a].tmp,use=filter,mode=disjoint,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); my $selcct_com3 = $f->{COMANS}; if ($selcct_com3 != 0){ $f->COM ("sel_delete"); } $f->COM ("sel_ref_feat,layers=$mask[$a].tmp,use=filter,mode=cover,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); my $selcct_com2 = $f->{COMANS}; if ($selcct_com2 != 0){ $f->COM ("sel_delete"); } &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_resize,size=$Smd_opt_ftsz,corner_ctl=no"); &CopyLay("$mask[$a].tmpos","no",-$lbcyjz); $f->COM ("sel_resize,size=-$lbcyjz,corner_ctl=no"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_surf2outline,width=$lbcyjz"); &WorkLayer("$mask[$a].tmpos"); &CopyLay("$mask[$a].tmp","no",0); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &WorkLayer("$mask[$a].tmpp"); &CopyLay("$mask[$a].tmp","yes",0.5); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=0.4,corner_ctl=no"); &WorkLayer("$mask[$a]"); &CopyLay("$mask[$a].ds","no",0); &WorkLayer("$mask[$a].ds"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &WorkLayer("$mask[$a].smd"); $f->COM ("sel_resize,size=$tmopt,corner_ctl=no"); $f->COM ("sel_resize,size=$Suf_opt_yjsz,corner_ctl=no"); &CopyLay("$mask[$a].smds","no",-1); $f->COM ("sel_resize,size=-1,corner_ctl=no"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_surf2outline,width=1"); &WorkLayer("$mask[$a].smds"); &CopyLay("$mask[$a].smd","no",0); &WorkLayer("$mask[$a].smd"); &CopyLay("$mask[$a].tmp","yes",0); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("cur_atr_reset"); $f->COM ("cur_atr_set,attribute=.solder_defined"); $f->COM ("sel_change_atr,mode=add"); $f->COM ("cur_atr_reset"); $f->COM ("sel_ref_feat,layers=$mask[$a].ds,use=filter,mode=disjoint,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); my $selcct_com1 = $f->{COMANS}; if ($selcct_com1 != 0){ $f->COM ("sel_delete"); } $f->COM ("sel_ref_feat,layers=$mask[$a].ds,use=filter,mode=cover,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); $f->COM ("get_select_count"); my $selcct_com = $f->{COMANS}; if ($selcct_com != 0){ $f->COM ("sel_delete"); } &CopyLay("$mask[$a]","yes",0); $f->COM ("display_layer,name=$mask[$a].bk,display=yes,number=1"); $f->COM ("display_layer,name=$mask[$a],display=yes,number=2"); $f->COM ("work_layer,name=$mask[$a]"); &DelectLay( "$mask[$a].tmp", "$mask[$a].tmps", "$mask[$a].tmpp", "$mask[$a].tmppt", "$mask[$a].tmppd", "$mask[$a].tmpos", "$mask[$a].ds", "$mask[$a].tmppp", "$mask[$a].tmpppd", "$mask[$a].tmppp+++", "$mask[$a].smd", "$mask[$a].smds" ); $a++ } $mw->withdraw; &MessageDialoginfo("脚本运行完成,请认真核对备份层!"); exit; } sub do_arec { while (1) { $f->COM ("filter_reset,filter_name=popup"); $f->COM ("sel_clear_feat"); $f->COM ("clear_highlight"); $f->COM ("filter_set,filter_name=popup,update_popup=yes,feat_types=pad"); $f->COM ("filter_atr_set,filter_name=popup,condition=yes,attribute=.smd"); $f->COM ("filter_highlight"); $f->COM ("display_layer,name=$mask[$a],display=yes,number=2"); $f->MOUSE("r Please SELECT weizhi"); my @MOUSEANS=$f->{MOUSEANS}; my ($x1,$y1,$x2,$y2)=split /\s+/,$f->{MOUSEANS}; $f->COM("filter_area_strt"); $f->COM("filter_area_xy,x=$x1,y=$y1"); $f->COM("filter_area_xy,x=$x2,y=$y2"); $f->COM("filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=no"); $f->COM ("get_select_count"); my $selcct_fea = $f->{COMANS}; if ($selcct_fea != 0) { &CopyLay("$mask[$a].tmp","no",0); &WorkLayer("$mask[$a].tmp"); &CopyLay("$mask[$a].tmpp","no",0); &CopyLay("$mask[$a].smd","no",0); } else { $f->COM ("clear_highlight"); $f->COM ("filter_reset,filter_name=popup"); last; } &WorkLayer("$sign[$a]"); $f->COM("filter_reset,filter_name=popup"); $f->COM("filter_area_strt"); $f->COM("filter_area_xy,x=$x1,y=$y1"); $f->COM("filter_area_xy,x=$x2,y=$y2"); $f->COM("filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=yes"); &CopyLay("$mask[$a].tmppp","no",0); &WorkLayer("$mask[$a].tmpp"); if ($tmopt <= 0) { $jdzs = ($tmopt + $gxopt) * 2; $jdzsjdz = abs($jdzs); } else { $jdzs = 0.1; $jdzsjdz = 0; } &CopyLay("$mask[$a].tmppp","yes",$jdzs); &WorkLayer("$mask[$a].tmppp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=$Cov_opt_ftsz,corner_ctl=no"); &WorkLayer("$mask[$a].tmpp"); &CopyLay("$mask[$a].tmppp","yes",$Suf_opt_ftsz); &WorkLayer("$mask[$a].tmppp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=-1.5,corner_ctl=no"); &CopyLay("$mask[$a].tmpppd","no",0); $f->COM ("sel_surf2outline,width=1.5"); &WorkLayer("$mask[$a].tmpppd"); &CopyLay("$mask[$a].tmppp","no",0); $f->COM ("display_layer,name=$mask[$a].tmpp,display=yes,number=1"); $f->COM ("work_layer,name=$mask[$a].tmpp"); &WorkLayer("$mask[$a].tmpp"); $f->COM ("sel_resize,size=$Smd_opt_ftsz,corner_ctl=no"); &CopyLay("$mask[$a].tmppt","no",0); &WorkLayer("$mask[$a].tmppp"); &CopyLay("$mask[$a].tmpp","yes",0); &CopyLay("$mask[$a].tmppt","yes",10); &WorkLayer("$mask[$a].tmppt"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &CopyLay("$mask[$a].tmpp","no",0); &WorkLayer("$mask[$a].tmpp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=-$lbcyjz,corner_ctl=no"); &CopyLay("$mask[$a].tmppd","no",0); $f->COM ("sel_surf2outline,width=$lbcyjz"); &WorkLayer("$mask[$a].tmppd"); &CopyLay("$mask[$a].tmpp","no",0); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &WorkLayer("$mask[$a].tmpp"); $f->COM ("fill_params,type=solid,origin_type=datum,solid_type=fill,std_type=line,min_brush=2,use_arcs=yes,symbol=,dx=0.1,dy=0.1,std_angle=45,std_line_width=10,std_step_dist=50,std_indent=odd,break_partial=yes,cut_prims=no,outline_draw=no,outline_width=0,outline_invert=no"); $f->COM ("sel_fill"); $f->COM ("sel_contourize,accuracy=0.1,break_to_islands=yes,clean_hole_size=3,clean_hole_mode=x_and_y"); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_resize,size=-0.5,corner_ctl=no"); &WorkLayer("$mask[$a].tmpp"); $f->COM ("sel_ref_feat,layers=$mask[$a].tmp,use=filter,mode=disjoint,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); my $selcct_com3a = $f->{COMANS}; if ($selcct_com3a != 0){ $f->COM ("sel_delete"); } $f->COM ("sel_ref_feat,layers=$mask[$a].tmp,use=filter,mode=cover,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); my $selcct_com2a = $f->{COMANS}; if ($selcct_com2a != 0){ $f->COM ("sel_delete"); } &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_resize,size=$Smd_opt_ftsz,corner_ctl=no"); &CopyLay("$mask[$a].tmpos","no",-$lbcyjz); $f->COM ("sel_resize,size=-$lbcyjz,corner_ctl=no"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_surf2outline,width=$lbcyjz"); &WorkLayer("$mask[$a].tmpos"); &CopyLay("$mask[$a].tmp","no",0); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &WorkLayer("$mask[$a].tmpp"); &CopyLay("$mask[$a].tmp","yes",0.5); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_resize,size=0.4,corner_ctl=no"); &WorkLayer("$mask[$a]"); &CopyLay("$mask[$a].ds","no",0); &WorkLayer("$mask[$a].ds"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); &WorkLayer("$mask[$a].smd"); $f->COM ("sel_resize,size=$tmopt,corner_ctl=no"); $f->COM ("sel_resize,size=$Suf_opt_yjsz,corner_ctl=no"); &CopyLay("$mask[$a].smds","no",-1); $f->COM ("sel_resize,size=-1,corner_ctl=no"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes"); $f->COM ("sel_surf2outline,width=1"); &WorkLayer("$mask[$a].smds"); &CopyLay("$mask[$a].smd","no",0); &WorkLayer("$mask[$a].smd"); &CopyLay("$mask[$a].tmp","yes",0); &WorkLayer("$mask[$a].tmp"); $f->COM ("sel_cont_resize,accuracy=0.1,break_to_islands=yes,island_size=0,hole_size=0,drill_filter=no,corner_ctl=yes "); $f->COM ("cur_atr_reset"); $f->COM ("cur_atr_set,attribute=.solder_defined"); $f->COM ("sel_change_atr,mode=add"); $f->COM ("cur_atr_reset"); $f->COM ("sel_ref_feat,layers=$mask[$a].ds,use=filter,mode=disjoint,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); my $selcct_com1a = $f->{COMANS}; if ($selcct_com1a != 0){ $f->COM ("sel_delete"); } $f->COM ("sel_ref_feat,layers=$mask[$a].ds,use=filter,mode=cover,pads_as=shape,f_types=line\;pad\;surface\;arc\;text,polarity=positive\;negative,include_syms=,exclude_syms="); $f->COM ("get_select_count"); my $selcct_coma = $f->{COMANS}; if ($selcct_coma != 0){ $f->COM ("sel_delete"); } $f->COM ("sel_copy_other,dest=layer_name,target_layer=$mask[$a],invert=yes,dx=0,dy=0,size=0,x_anchor=0,y_anchor=0,rotation=0,mirror=none"); &CopyLay("$mask[$a]","yes",0); $f->COM ("display_layer,name=$sign[$a],display=yes,number=1"); $f->COM ("display_layer,name=$mask[$a],display=yes,number=2"); $f->COM ("work_layer,name=$sign[$a]"); &DelectLay( "$mask[$a].tmp", "$mask[$a].tmps", "$mask[$a].tmpp", "$mask[$a].tmppt", "$mask[$a].tmppd", "$mask[$a].tmpos", "$mask[$a].ds", "$mask[$a].tmppp", "$mask[$a].tmpppd", "$mask[$a].tmppp+++", "$mask[$a].smd", "$mask[$a].smds" ); $f->COM ("clear_highlight"); $f->COM ("filter_reset,filter_name=popup"); } } ##########################函数区########################## sub SelAttCopy { #属性选择 my ($attribute,$text,$option,$tolay,$invert,$size) = @_; $f->COM("filter_reset,filter_name=popup"); $f->COM ("filter_set,filter_name=popup,update_popup=yes,feat_types=pad"); $f->COM("filter_atr_set,filter_name=popup,condition=yes,attribute=$attribute,text=$text,option=$option"); $f->COM("filter_area_strt"); $f->COM("filter_area_end,layer=,filter_name=popup,operation=select,area_type=none,inside_area=no,intersect_area=no"); $f->COM("get_select_count"); my $selShul = $f->{COMANS}; return $selShul; } sub CopyLay { #复制层 my ($target_layer,$invert,$size) = @_; $f->COM("sel_copy_other,dest=layer_name,target_layer=$target_layer,invert=$invert,dx=0,dy=0,size=$size,x_anchor=0,y_anchor=0,rotation=0,mirror=none"); } sub DelectLay { #删除层(接收多个参数) $f->VOF(); foreach(@_){ $f->COM("delete_layer,layer=$_"); } $f->VON(); } sub WorkLayer { #工作层 my $WorkLay = shift; $f->COM("affected_layer,mode=all,affected=no"); $f->COM("clear_layers"); $f->COM("filter_reset,filter_name=popup"); $f->COM("display_layer,name=$WorkLay,display=yes,number=1"); $f->COM("work_layer,name=$WorkLay"); } sub ClearLayer { #层初始化 my $WorkLay = shift; $f->COM("affected_layer,mode=all,affected=no"); $f->COM("clear_layers"); $f->COM("filter_reset,filter_name=popup"); } sub helps { my $mw = MainWindow->new( -title =>"关于脚本",-background => "#CDD2E4"); $mw->geometry("560x680+800+100"); $mw->resizable(0,0); $mw->update; # if ($Sys_name =~ /Linux/) { # $mw->iconimage($logo3); # } else { # $mw->iconbitmap("$ImgPath/ncc.ico"); # } my $helps_log = $mw->Photo('info',-file => "$ImgPath/hp.xpm"); $mw ->Label(-image => $helps_log, -border => 1, -relief => 'solid',)->pack(-side => 'top',-padx => 1,-pady => 1); $mw->Label( -text => "注意事项及免责申明\n". "1.参数设置部分需根据本厂的具体工艺要求合理设置,特殊要求可视情况定制,\n". "2.使用推荐范围内的参数,综合管控及细节处理效果更佳,\n". "3.脚本运行不干涉防焊层,直接以负片的形式做出,请在运行脚本后再做塞孔处理,\n". "4.请认真核对备份层,以免造成未知错误对您产生影响,\n". "5.脚本可以提升效率及品质但不能替代人的作用,可信赖脚本但不可依赖,\n". "6.对于使用本脚本产生任何不良影响与脚本制作者无关,\n". "7.如您继续使用此脚本表示您已接受以上所有条款!\n", -font => '宋体 10', -background => "#CDD2E4" )->pack(-side => 'top',); $mw->Label( -text => "技术在于碰撞,欢迎大家批评指教,望大家共同努力共同进步!", -fg => 'blue', -font => '宋体 10', -background => "#CDD2E4", )->pack(-side => 'top',); $mw->Button( -text => '确定',-command => sub {$mw->destroy;}, -width => 8, -font=> '宋体 10', -height=> 1, -background => "#A1AEE1" )->pack(-side => 'right', -padx => 12, -pady => 12); $mw->Label( -text => "\n\n Copyright © 2017 Twei Tang. All rights reserved ", -fg => 'red', -font => '宋体 10', -background => "#CDD2E4", )->pack(-side => 'right',); MainLoop; } sub scroll { $messbs = substr($messbs, 1) . substr($messbs, 0, 1); } sub timeout { $mess = strftime("当前时间: %Y-%m-%d %H:%M:%S 第"."$Week"."周 当前系统: $lVer",localtime()); } sub GetUserSymtem { #获取系统名 my $Sys; if ($^O =~ /linux/) { $Sys = "Linux"; } elsif ($^O =~ /MSWin32/) { $Sys = "Windows"; } else { $Sys = "其它"; } return $Sys; } sub GetUserGroup { #获取用户组 $f->COM('get_user_group'); return $f->{COMANS}; } sub GetUserName { #获取用户名 $f->COM('get_user_name'); return $f->{COMANS}; } sub GetUserPrive { #获取用户权限 $f->COM('get_user_priv'); my @priv = split(/\s+/,$f->{COMANS}); return $priv[0]; } sub MessageDialog { #提示信息窗口 my $title = shift; my $icon = shift; my $type = shift; my $message = shift; $mw->messageBox( -icon => $icon, -message => $message, -title =>$title, ($Sys_name =~ /Linux/) ? (-font => $Font, -background => '#EDECEB', -bg => '#CDD2E4', -wraplength => '7i',-type => $type) : (-type => $type) ); return $type; } sub MessageDialogError { #错误提示窗口 $mw->withdraw; &MessageDialog('错误提示','error','ok',shift); exit; } sub MessageDialogWarn { #警告信息窗口 &MessageDialog('警告信息','error','ok',shift); } sub MessageDialoginfo { #操作信息窗口 &MessageDialog('操作信息','info','ok',shift); } ##########################函数区########################## 注意:这个是使用perl语言的TK GUI写的代码,请你把他变为activeperl TKX GUI的代码,要求实现的功能一模一样,不能添加新的库文件,我懒得添加
07-14
/** * @notes 京东收派服务费明细导入(优化版本) * @notes 技术核心优势在于通过分块读取和分批处理,将原本可能导致内存溢出的大数据导入任务,转化为多个小而可控的操作单元,从而在处理超大型 Excel 文件时保持稳定性 * @notes 十上百万的excel表格可能导入效率会慢 但是很稳定 不至于报错502或者超时等错误... * @notes 如果遇到上百万的excel表格请同步设置nginx的如下配置: * 代理相关超时配置(2个小时或者更长) * proxy_connect_timeout 7200; * proxy_read_timeout 7200; * proxy_send_timeout 7200; * fastcgi相关超时配置(2个小时或者更长) * fastcgi_connect_timeout 7200; * fastcgi_read_timeout 7200; * fastcgi_send_timeout 7200; * 可以确保虽然慢但是稳定的导入! * @return Json * @author 胡军 */ public function importExcel(): Json { // 设置脚本执行时间无限制,避免大数据处理超时 set_time_limit(0); // 设置脚本最大内存使用量为2GB,处理大文件时避免内存溢出 ini_set('memory_limit', '2048M'); // 获取请求参数(包含上传的文件信息) $params = $this->request->param(); // 验证文件是否上传 if (empty($params["file"])) { return $this->fail('请上传要导入文件'); } // 定义Excel表头与数据库字段的映射关系 $titleArr = [ '商家编号' => 'merchant_code', '业务单号' => 'business_order_number', '平台订单号' => 'platform_order_number', '商家订单号' => 'merchant_order_number', '退回件关联运单号' => 'return_waybill_number', '店铺名称' => 'shop_name', '下单时间' => 'order_time', '始发省' => 'origin_province', '始发市' => 'origin_city', '目的省' => 'destination_province', '目的市' => 'destination_city', '计费重量' => 'billing_weight', '实际重量(kg)' => 'actual_weight_kg', '实际体积(cm3)' => 'actual_volume_cm3', '首重单价' => 'first_weight_price', '续重单价' => 'continued_weight_price', '包裹/耗材数量' => 'package_material_quantity', '销售平台订单号' => 'sales_platform_order_number', '费用类型' => 'fee_type', '原始金额' => 'original_amount', '折扣/促销金额' => 'discount_promotion_amount', '计费时间' => 'billing_time', '结算金额' => 'settlement_amount', '签收时间' => 'sign_time', '商品编码' => 'product_code', '商品名称' => 'product_name' ]; try { // 构建上传文件的完整路径 $path = app()->getRootPath() . "public/" . $params['file']; // 1. 创建Excel读取器并设置为只读取数据模式(优化内存) $reader = IOFactory::createReaderForFile($path); $reader->setReadDataOnly(true); // 2. 获取工作表基本信息(总行数和最大列字母),避免加载整个文件 $worksheetInfo = $reader->listWorksheetInfo($path); $totalRows = $worksheetInfo[0]['totalRows']; $highestColumn = $worksheetInfo[0]['lastColumnLetter']; // 3. 读取表头行(仅加载第一行数据) $chunkFilter = new ChunkReadFilter(); $chunkFilter->setRows(1, 1); $reader->setReadFilter($chunkFilter); $spreadsheet = $reader->load($path); $sheet = $spreadsheet->getSheet(0); $title = $sheet->rangeToArray('A1:' . $highestColumn . '1', null, true, true, true)[1]; // 释放不再使用的Spreadsheet对象,减少内存占用 $spreadsheet->disconnectWorksheets(); unset($spreadsheet); // 检查表头是否存在 if (empty($title)) { throw new \Exception('Excel表头为空'); } // 初始化数据库模型和计数器 $model = new DeliveryPrimaryRegionsItemizationModel(); //TODO:根据自身mysql所在服务的性能来控制批量插入大小 不然报错或者导入很慢 该值需要反复测验找到最合适的大小 $insertBatchSize = 2000; // 数据库插入批次大小 $total = 0; // 总记录数 $success = 0; // 成功处理记录数 $failedBatches = []; // 失败批次记录 $batchData = []; // 批次数据临时存储 $processedRows = 0; // 已处理行数 // 4. 分块处理Excel数据,每次处理$chunkSize行 //TODO:根据自身服务器性能来决定每次分块读取excel表格数据的条数 不然报错或者导入很慢 该值需要反复测验找到最合适的大小 $chunkSize = 5000; // 每次加载5000行 $chunkFilter = new ChunkReadFilter(); $reader->setReadFilter($chunkFilter); // 循环处理每个数据块 for ($startRow = 2; $startRow <= $totalRows; $startRow += $chunkSize) { $endRow = min($startRow + $chunkSize - 1, $totalRows); $chunkFilter->setRows($startRow, $chunkSize); // 5. 加载当前数据块 $spreadsheet = $reader->load($path); $sheet = $spreadsheet->getSheet(0); // 6. 处理当前块中的每一行数据 for ($row = $startRow; $row <= $endRow; $row++) { // 获取当前行数据 $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, null, true, true, true)[$row]; $item = []; // 将Excel列名映射为数据库字段名 // 将Excel列名映射为数据库字段名 foreach ($rowData as $colIndex => $value) { $colName = $title[$colIndex] ?? ''; if ($colName && isset($titleArr[$colName])) { $field = $titleArr[$colName]; $rawValue = trim($value ?? ''); // 原始值去除首尾空格 // 处理decimal类型字段 $decimalFields = [ 'billing_weight', 'theoretical_weight', 'weight_rounded', 'weight_difference', 'actual_weight_kg', 'actual_volume_cm3', 'first_weight_price', 'continued_weight_price', 'original_amount', 'discount_promotion_amount', 'settlement_amount', 'verification_difference', 'theoretical_billing', 'theoretical_difference', 'non_cross_warehouse_fee', 'cross_warehouse_difference', 'continued_weight_price2' ]; if (in_array($field, $decimalFields)) { // 空值处理:空字符串/空格 → 转为null(需数据库允许null)或0 if ($rawValue === '') { $item[$field] = null; // 若数据库不允许null,可改为0 } // 非数值处理:过滤为0(或记录错误日志) elseif (!is_numeric($rawValue)) { // 可选:记录错误行号和内容,方便排查 // $this->recordError($row, $colName, "非数值内容: {$rawValue}"); $item[$field] = 0; } // 数值格式化:保留2位小数(根据数据库字段定义调整) else { $item[$field] = round((float)$rawValue, 2); } } // 其他字段保持原处理(如字符串、整数等) else { $item[$field] = $rawValue; } } } // print_r($item);die; // 如果行数据不为空,则添加到批次数据中 if (!empty($item)) { $batchData[] = $item; $processedRows++; } // 7. 当批次数据达到插入批次大小时,执行数据库插入操作 if (count($batchData) >= $insertBatchSize) { $this->processBatch($model, $batchData, $success, $failedBatches, $total); $batchData = []; // 清空批次数据 } $total++; // 总记录数递增 } // 8. 释放当前数据块占用的内存 $spreadsheet->disconnectWorksheets(); unset($spreadsheet); gc_collect_cycles(); // 触发垃圾回收 // 9. 输出处理进度信息 $progress = round(($endRow / $totalRows) * 100, 2); echo "处理进度: {$progress}% | 已处理: {$processedRows} 行\n"; } // 10. 处理剩余不足一个批次的数据 if (!empty($batchData)) { $this->processBatch($model, $batchData, $success, $failedBatches, $total); } // 返回处理结果 if (empty($failedBatches)) { $resultMsg = "导入成功,共{$total}条数据,成功导入{$success}条"; return $this->success($resultMsg); } else { $errorCount = $total - $success; $errorMsg = "失败 {$errorCount} 条,第一个错误: {$failedBatches[0]['error']}"; return $this->fail('导入失败', ['remark' => $errorMsg]); } } catch (\Exception $e) { // 异常处理,返回错误信息 return $this->fail('导入过程中出错: ' . $e->getMessage()); } } /** * 处理数据批次(优化SQL构建) */ private function processBatch($model, &$batchData, &$success, &$failedBatches, &$total) { // 如果批次数据为空则直接返回 if (empty($batchData)) return; try { // 使用参数绑定构建SQL语句,防止SQL注入 $tableName = $model->getTable(); $fields = array_keys($batchData[0]); $fieldList = '`' . implode('`, `', $fields) . '`'; $placeholders = '(' . implode(',', array_fill(0, count($fields), '?')) . ')'; $sql = "INSERT INTO {$tableName} ({$fieldList}) VALUES "; $values = []; $params = []; // 构建批量插入的SQL语句和参数数组 foreach ($batchData as $row) { $values[] = $placeholders; foreach ($fields as $field) { $params[] = $row[$field] ?? null; } } $sql .= implode(',', $values); // 执行带参数绑定的SQL语句 // 一定不要使用模型去操作数据库 不然效率很低 原生的最好! Db::execute($sql, $params); // 更新成功记录数 $success += count($batchData); // 清空批次数据 $batchData = []; } catch (\Exception $e) { // 记录失败批次信息 $failedBatches[] = [ 'startRow' => $total - count($batchData) + 1, 'endRow' => $total, 'error' => $e->getMessage() ]; // 出错时清空批次数据,避免重复处理 $batchData = []; } } /** * 分块读取过滤器 * 用于控制只读取Excel文件中的指定行范围 * common.php代码不规范导致本地git有差异直接还原 直接写在控制器里算了! */ class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter { private $startRow = 0; private $endRow = 0; // 设置要读取的起始行和行数 public function setRows($startRow, $chunkSize) { $this->startRow = $startRow; $this->endRow = $startRow + $chunkSize; } // 判断当前单元格是否应该被读取 public function readCell($column, $row, $worksheetName = '') { // 只读取指定范围内的行 if ($row >= $this->startRow && $row <= $this->endRow) { return true; } return false; } } 我需要导入100万的数据,并且excel表格当中26个字段 每个字段都特别的长,导入的时候总是报错502,字段少的时候就没事,请为我分析具体原因,另外请帮我针对问题进行代码优化,要求提供完整的代码哈 不要忘记注释信息
07-09
请整理出以下程序包中,关于“结算方式”的取值逻辑create or replace PACKAGE BODY cux_ap_schedule_pkg2 IS PROCEDURE main_bak(p1 OUT VARCHAR2, p2 OUT VARCHAR2, p_org_id IN NUMBER, p_vendor_f IN VARCHAR2, p_vendor_t IN VARCHAR2, p_gl_date_f IN VARCHAR2, p_gl_date_t IN VARCHAR2, p_due_date_f IN VARCHAR2, p_due_date_t IN VARCHAR2, p_yn in varchar2) IS -- v_gl_date_f DATE := trunc(fnd_date.canonical_to_date(p_gl_date_f)); v_gl_date_t DATE := trunc(fnd_date.canonical_to_date(p_gl_date_t)); v_due_date_f DATE := trunc(fnd_date.canonical_to_date(p_due_date_f)); v_due_date_t DATE := trunc(fnd_date.canonical_to_date(p_due_date_t)); v_org_name VARCHAR2(300); -- CURSOR cur_schedule IS SELECT pv.vendor_name --供应商名称 , pvsa.vendor_site_code --供应商地址 , aia.invoice_id, aia.invoice_num --发票编号 , b.displayed_field, ats.name term_name --付款方法 , to_char(aia.gl_date, 'YYYY-MM-DD') gl_date --总帐日期 , to_char(aia.invoice_date, 'YYYY-MM-DD') invoice_date --发票日期 , to_char(aia.terms_date, 'YYYY-MM-DD') terms_date --条件日期 , to_char(apsa.due_date, 'YYYY-MM-DD') due_date --到期日 , aia.invoice_currency_code --币种 , aia.invoice_amount --原币 , nvl(aia.invoice_amount, 0) * nvl(aia.exchange_rate, 1) invoice_amount_b --本位币 , apsa.amount_remaining --到期余额原币 , nvl(apsa.amount_remaining, 0) * nvl(aia.exchange_rate, 1) amount_remaining_b --到期余额本币 , aia.description --摘要 , cuxs_std_report_utl_pkg.get_ccid_segment(gcc.code_combination_id) acc_code, cuxs_std_report_utl_pkg.get_ccid_description(gcc.chart_of_accounts_id, gcc.code_combination_id) acc_desc, decode(NVL(apsa.hold_flag, 'N'), 'N', '否', '是') HOLD_FLAG, ppx.EMPLOYEE_NUMBER FROM ap_payment_schedules_all apsa, po_vendors pv, po_vendor_sites_all pvsa, ap_terms ats, ap_invoices_all aia, ap_lookup_codes b, gl_code_combinations gcc, per_people_x ppx WHERE apsa.invoice_id = aia.invoice_id AND aia.terms_id = ats.term_id AND aia.vendor_id = pv.vendor_id(+) AND aia.vendor_site_id = pvsa.vendor_site_id(+) and pv.EMPLOYEE_ID = ppx.PERSON_ID(+) AND apsa.amount_remaining <> 0 -- AND aia.org_id = p_org_id /*AND pv.segment1 >= nvl(pv.segment1, p_vendor_f) AND pv.segment1 <= nvl(pv.segment1, p_vendor_t)*/ AND aia.invoice_type_lookup_code = b.lookup_code AND b.lookup_type(+) = 'INVOICE TYPE' AND AP_INVOICES_PKG.GET_APPROVAL_STATUS(aia.INVOICE_ID, aia.INVOICE_AMOUNT, aia.PAYMENT_STATUS_FLAG, aia.INVOICE_TYPE_LOOKUP_CODE) NOT IN ('NEEDS REAPPROVAL', 'NEVER APPROVED', 'CANCELLED', 'FULL', 'UNAPPROVED') AND aia.accts_pay_code_combination_id = gcc.code_combination_id(+) AND (pv.segment1 >= p_vendor_f OR p_vendor_f IS NULL) AND (pv.segment1 <= p_vendor_t OR p_vendor_t IS NULL) AND trunc(aia.gl_date) >= trunc(nvl(v_gl_date_f, aia.gl_date)) AND trunc(aia.gl_date) <= trunc(nvl(v_gl_date_t, aia.gl_date)) AND trunc(apsa.due_date) >= trunc(nvl(v_due_date_f, apsa.due_date)) AND trunc(apsa.due_date) <= trunc(nvl(v_due_date_t, apsa.due_date)) ORDER BY pv.vendor_name, to_char(aia.invoice_date, 'YYYY-MM-DD'), aia.invoice_num; cursor cur_pro(p_invoice_id number) is select nvl(ppa1.project_id, ppa.PROJECT_ID) project_id, nvl(ppa1.SEGMENT1, ppa.SEGMENT1) pro_num, nvl(ppa1.NAME, ppa.NAME) pro_name, pav.agent_name, (select d.kb from per_people_x ppx, CUX.CUX_HR_EMPLOYEE_T emp, cux_hr_dept d where ppx.EMPLOYEE_NUMBER = emp.emp_no and emp.ou_code = d.ou_code and ppx.PERSON_ID = pav.agent_id and rownum = 1) kb, case when sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) = 0 then 0 else sum(d.AMOUNT) / sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) end pro_rate from ap_invoices_all h, ap_invoice_distributions_all d, po_distributions_all pd, po_headers_all ph, po_agents_v pav, pa_projects_all ppa, pa_projects_all ppa1 where h.INVOICE_ID = d.INVOICE_ID and d.PO_DISTRIBUTION_ID = pd.PO_DISTRIBUTION_ID(+) and pd.PO_HEADER_ID = ph.PO_HEADER_ID(+) and ph.AGENT_ID = pav.agent_id(+) and nvl(d.PROJECT_ID, h.PROJECT_ID) = ppa1.PROJECT_ID(+) and pd.PROJECT_ID = ppa.PROJECT_ID(+) and h.INVOICE_ID = p_invoice_id and d.LINE_TYPE_LOOKUP_CODE <> 'PREPAY' group by h.INVOICE_ID, nvl(ppa1.project_id, ppa.PROJECT_ID), nvl(ppa1.SEGMENT1, ppa.SEGMENT1), nvl(ppa1.NAME, ppa.NAME), pav.agent_name, pav.agent_id; p_ret_flag VARCHAR2(2); v_sep VARCHAR2(15); --字符串之间的分隔符号,默认为逗号“,” v_line_str VARCHAR2(4000); --输出的字符串,不同的字段之间,使用V_SEP变量表示的分隔符号进行分隔 p_title VARCHAR2(100); lv_pro_attr1 varchar2(200); lv_pro_attr2 varchar2(200); lv_pro_attr3 varchar2(200); lv_pro_attr4 varchar2(200); lv_pro_attr5 varchar2(200); lv_pro_class varchar2(200); lv_pro_class2 varchar2(200); BEGIN -- BEGIN SELECT hou.name INTO v_org_name FROM hr_operating_units hou WHERE hou.organization_id = p_org_id; EXCEPTION WHEN OTHERS THEN v_org_name := NULL; END; -- p_ret_flag := 'Y'; p_title := '付款计划表'; -- --表示以文件形式进行输出,在开发HTML报表时,固定即可,不需修改 -- cux_html_reports_utl.v_report_output_mode := 'F'; v_sep := cux_html_reports_utl.g_delimiter; --输出报表标题 cux_html_reports_utl.html_title(p_program_title => p_title, p_report_title => p_title); --标题输出 cux_html_reports_utl.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --输出参数 -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '实体:', p_para_value => v_org_name); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商从:', p_para_value => p_vendor_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商至:', p_para_value => p_vendor_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期从:', p_para_value => p_gl_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期至:', p_para_value => p_gl_date_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日从:', p_para_value => p_due_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日至:', p_para_value => p_due_date_t); END IF; --开始进行内容的输出,下行的width=1200,用于进行输出表格的宽度设置 --cux_html_report_pkg.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --将表格标题,用逗号分隔后,连接成一个字符串,注意:最后一个字段之后,也要有个逗号。 if p_yn = 'N' then v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,发票金额原币,发票金额本币,到期余额原币,到期余额本币,摘要,是否暂挂,负债账户,负债说明,'; --输出表格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); -- FOR rec_schedule IN cur_schedule LOOP cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || rec_schedule.invoice_amount || v_sep || rec_schedule.invoice_amount_b || v_sep || rec_schedule.amount_remaining || v_sep || rec_schedule.amount_remaining_b || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); END LOOP; else v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,项目编码,项目名称,项目大分类,项目分类,项目代码,项目发票金额原币,项目发票金额本币,项目到期余额原币,项目到期余额本币,摘要,是否暂挂,负债账户,负债说明,采购员,组别,'; --输出表格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); -- FOR rec_schedule IN cur_schedule LOOP for l in cur_pro(rec_schedule.invoice_id) loop SCUX_CST_INVEST_REPORT_PKG.get_project_info2(l.project_id, null, lv_pro_attr1, lv_pro_attr2, lv_pro_attr3, lv_pro_attr4, lv_pro_attr5, lv_pro_class, lv_pro_class2); cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || l.pro_num || v_sep || l.pro_name || v_sep || lv_pro_class2 || v_sep || lv_pro_class || v_sep || lv_pro_attr3 || v_sep || rec_schedule.invoice_amount * l.pro_rate || v_sep || rec_schedule.invoice_amount_b * l.pro_rate || v_sep || rec_schedule.amount_remaining * l.pro_rate || v_sep || rec_schedule.amount_remaining_b * l.pro_rate || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep || l.agent_name || v_sep || l.kb || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); end loop; end loop; end if; END; PROCEDURE main(p1 OUT VARCHAR2, p2 OUT VARCHAR2, p_org_id IN NUMBER, p_vendor_f IN VARCHAR2, p_vendor_t IN VARCHAR2, p_gl_date_f IN VARCHAR2, p_gl_date_t IN VARCHAR2, p_due_date_f IN VARCHAR2, p_due_date_t IN VARCHAR2, p_yn in varchar2 ,P_save In Varchar2 Default 'N' ) IS -- v_gl_date_f DATE := trunc(fnd_date.canonical_to_date(p_gl_date_f)); v_gl_date_t DATE := trunc(fnd_date.canonical_to_date(p_gl_date_t)); v_due_date_f DATE := trunc(fnd_date.canonical_to_date(p_due_date_f)); v_due_date_t DATE := trunc(fnd_date.canonical_to_date(p_due_date_t)); v_org_name VARCHAR2(300); lr_ex_info cux_ap_schd_extra_t %rowtype; ln_request_id number := fnd_global.CONC_REQUEST_ID; ld_crr_date date := sysdate; l_extra9 VARCHAR2(50) :='达标'; l_extra10 VARCHAR2(50) :='正常'; -- CURSOR cur_schedule IS SELECT pv.vendor_name --供应商名称 , pv.VENDOR_ID, aia.GL_DATE gl_date_d, aia.INVOICE_DATE invoice_date_d, aia.TERMS_DATE terms_date_d, apsa.DUE_DATE due_date_d, pvsa.vendor_site_code --供应商地址 , aia.invoice_id, aia.invoice_num --发票编号 , b.displayed_field, ats.name term_name --付款方法 , to_char(aia.gl_date, 'YYYY-MM-DD') gl_date --总帐日期 , to_char(aia.invoice_date, 'YYYY-MM-DD') invoice_date --发票日期 , to_char(aia.terms_date, 'YYYY-MM-DD') terms_date --条件日期 , to_char(apsa.due_date, 'YYYY-MM-DD') due_date --到期日 , aia.invoice_currency_code --币种 , aia.invoice_amount --原币 , nvl(aia.invoice_amount, 0) * nvl(aia.exchange_rate, 1) invoice_amount_b --本位币 , apsa.amount_remaining --到期余额原币 , nvl(apsa.amount_remaining, 0) * nvl(aia.exchange_rate, 1) amount_remaining_b --到期余额本币 , aia.description --摘要 , cuxs_std_report_utl_pkg.get_ccid_segment(gcc.code_combination_id) acc_code, cuxs_std_report_utl_pkg.get_ccid_description(gcc.chart_of_accounts_id, gcc.code_combination_id) acc_desc, decode(NVL(apsa.hold_flag, 'N'), 'N', '否', '是') HOLD_FLAG, ppx.EMPLOYEE_NUMBER FROM ap_payment_schedules_all apsa, po_vendors pv, po_vendor_sites_all pvsa, ap_terms ats, ap_invoices_all aia, ap_lookup_codes b, gl_code_combinations gcc, per_people_x ppx WHERE apsa.invoice_id = aia.invoice_id AND aia.terms_id = ats.term_id AND aia.vendor_id = pv.vendor_id(+) AND aia.vendor_site_id = pvsa.vendor_site_id(+) and pv.EMPLOYEE_ID = ppx.PERSON_ID(+) AND apsa.amount_remaining <> 0 -- and NVL(apsa.hold_flag, 'N')='N' -- AND aia.org_id = p_org_id /*AND pv.segment1 >= nvl(pv.segment1, p_vendor_f) AND pv.segment1 <= nvl(pv.segment1, p_vendor_t)*/ AND aia.invoice_type_lookup_code = b.lookup_code AND b.lookup_type(+) = 'INVOICE TYPE' AND AP_INVOICES_PKG.GET_APPROVAL_STATUS(aia.INVOICE_ID, aia.INVOICE_AMOUNT, aia.PAYMENT_STATUS_FLAG, aia.INVOICE_TYPE_LOOKUP_CODE) NOT IN ('NEEDS REAPPROVAL', 'NEVER APPROVED', 'CANCELLED', 'FULL', 'UNAPPROVED') AND aia.accts_pay_code_combination_id = gcc.code_combination_id(+) AND (pv.segment1 >= p_vendor_f OR p_vendor_f IS NULL) AND (pv.segment1 <= p_vendor_t OR p_vendor_t IS NULL) AND trunc(aia.gl_date) >= trunc(nvl(v_gl_date_f, aia.gl_date)) AND trunc(aia.gl_date) <= trunc(nvl(v_gl_date_t, aia.gl_date)) AND trunc(apsa.due_date) >= trunc(nvl(v_due_date_f, apsa.due_date)) AND trunc(apsa.due_date) <= trunc(nvl(v_due_date_t, apsa.due_date)) ORDER BY pv.vendor_name, to_char(aia.invoice_date, 'YYYY-MM-DD'), aia.invoice_num; cursor cur_pro(p_invoice_id number) is select nvl(ppa1.project_id, ppa.PROJECT_ID) project_id, nvl(ppa1.SEGMENT1, ppa.SEGMENT1) pro_num, nvl(ppa1.NAME, ppa.NAME) pro_name, nvl(pt1.ATTRIBUTE1,pt.ATTRIBUTE1) CU, pav.agent_name, (select d.kb from per_people_x ppx, CUX.CUX_HR_EMPLOYEE_T emp, cux_hr_dept d where ppx.EMPLOYEE_NUMBER = emp.emp_no and emp.ou_code = d.ou_code and ppx.PERSON_ID = pav.agent_id and rownum = 1) kb, case when sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) = 0 then 0 else sum(d.AMOUNT) / sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) end pro_rate from ap_invoices_all h, ap_invoice_distributions_all d, po_distributions_all pd, po_headers_all ph, po_agents_v pav, pa_projects_all ppa, pa_projects_all ppa1, pa_tasks pt, pa_tasks pt1 where h.INVOICE_ID = d.INVOICE_ID and d.PO_DISTRIBUTION_ID = pd.PO_DISTRIBUTION_ID(+) and pd.PO_HEADER_ID = ph.PO_HEADER_ID(+) and ph.AGENT_ID = pav.agent_id(+) and nvl(d.PROJECT_ID, h.PROJECT_ID) = ppa1.PROJECT_ID(+) and pd.PROJECT_ID = ppa.PROJECT_ID(+) and ppa.PROJECT_ID= pt.PROJECT_ID(+) and ppa1.PROJECT_ID = pt1.PROJECT_ID(+) and h.INVOICE_ID = p_invoice_id and d.LINE_TYPE_LOOKUP_CODE <> 'PREPAY' group by h.INVOICE_ID, nvl(ppa1.project_id, ppa.PROJECT_ID), nvl(ppa1.SEGMENT1, ppa.SEGMENT1), nvl(ppa1.NAME, ppa.NAME), nvl(pt1.ATTRIBUTE1,pt.ATTRIBUTE1), pav.agent_name, pav.agent_id; p_ret_flag VARCHAR2(2); v_sep VARCHAR2(15); --字符串之间的分隔符号,默认为逗号“,” v_line_str VARCHAR2(4000); --输出的字符串,不同的字段之间,使用V_SEP变量表示的分隔符号进行分隔 p_title VARCHAR2(100); lv_pro_attr1 varchar2(200); lv_pro_attr2 varchar2(200); lv_pro_attr3 varchar2(200); lv_pro_attr4 varchar2(200); lv_pro_attr5 varchar2(200); lv_pro_class varchar2(200); lv_pro_class2 varchar2(200); ln_bill_months number; ln_pay_months number; BEGIN -- BEGIN SELECT hou.name INTO v_org_name FROM hr_operating_units hou WHERE hou.organization_id = p_org_id; EXCEPTION WHEN OTHERS THEN v_org_name := NULL; END; -- p_ret_flag := 'Y'; p_title := '付款计划表'; -- --表示以文件形式进行输出,在开发HTML报表时,固定即可,不需修改 -- cux_html_reports_utl.v_report_output_mode := 'F'; v_sep := cux_html_reports_utl.g_delimiter; --输出报表标题 cux_html_reports_utl.html_title(p_program_title => p_title, p_report_title => p_title); --标题输出 cux_html_reports_utl.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --输出参数 -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '实体:', p_para_value => v_org_name); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商从:', p_para_value => p_vendor_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商至:', p_para_value => p_vendor_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期从:', p_para_value => p_gl_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期至:', p_para_value => p_gl_date_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日从:', p_para_value => p_due_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日至:', p_para_value => p_due_date_t); END IF; --开始进行内容的输出,下行的width=1200,用于进行输出表格的宽度设置 --cux_html_report_pkg.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --将表格标题,用逗号分隔后,连接成一个字符串,注意:最后一个字段之后,也要有个逗号。 if p_yn = 'N' then v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,发票金额原币,发票金额本币,到期余额原币,到期余额本币,摘要,是否暂挂,负债账户,负债说明,'; --输出表格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); -- FOR rec_schedule IN cur_schedule LOOP cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || rec_schedule.invoice_amount || v_sep || rec_schedule.invoice_amount_b || v_sep || rec_schedule.amount_remaining || v_sep || rec_schedule.amount_remaining_b || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); END LOOP; else v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,BU,CU,项目编码,项目名称,项目大分类,项目分类,项目代码,项目发票金额原币,项目发票金额本币,项目到期余额原币,项目到期余额本币,摘要,是否暂挂, 负债账户,负债说明,采购员,组别,物料类型,采购地点,结算账期,付款方式,结算方式,支付账期,付款说明,限额,是否达标,备注,'; --输出表格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); if P_save='Y' then delete from cux_ap_schd_extra_t; end if; FOR rec_schedule IN cur_schedule LOOP for l in cur_pro(rec_schedule.invoice_id) loop lr_ex_info := null; lr_ex_info.gl_date := rec_schedule.gl_date_d; lr_ex_info.vendor_name := rec_schedule.vendor_name; lr_ex_info.emp_num := rec_schedule.employee_number; lr_ex_info.site_name := rec_schedule.vendor_site_code; lr_ex_info.invoice_num := rec_schedule.invoice_num; lr_ex_info.invoice_type := rec_schedule.displayed_field; lr_ex_info.term_date := rec_schedule.terms_date_d; lr_ex_info.term_name := rec_schedule.term_name; lr_ex_info.gl_date := rec_schedule.gl_date_d; lr_ex_info.invoice_date := rec_schedule.invoice_date_d; lr_ex_info.due_date := rec_schedule.due_date_d; lr_ex_info.currency_code := rec_schedule.invoice_currency_code; lr_ex_info.proj_code := l.pro_num; lr_ex_info.proj_name := l.pro_name; lr_ex_info.proj_amount := rec_schedule.invoice_amount * l.pro_rate; lr_ex_info.proj_amount_b := rec_schedule.invoice_amount_b * l.pro_rate; lr_ex_info.proj_due_amount := rec_schedule.amount_remaining * l.pro_rate; lr_ex_info.proj_due_amount_b := rec_schedule.amount_remaining_b * l.pro_rate; lr_ex_info.description := rec_schedule.description; lr_ex_info.hold_flag := rec_schedule.hold_flag; lr_ex_info.cr_code := rec_schedule.acc_code; lr_ex_info.cr_desc := rec_schedule.acc_desc; lr_ex_info.agent_name := l.agent_name; lr_ex_info.dept := l.kb; lr_ex_info.request_id := ln_request_id; lr_ex_info.creation_date := ld_crr_date; begin select aa.SEGMENT1, cc.site,cc.big_cate into lr_ex_info.extra10, lr_ex_info.extra1,lr_ex_info.extra8 from (select item.SEGMENT1, row_number() over(order by d.AMOUNT desc) rnum from ap_invoice_distributions_all d, po_distributions_all pd, po_lines_all pl, mtl_system_items_b item where d.PO_DISTRIBUTION_ID = pd.PO_DISTRIBUTION_ID(+) and pd.PO_LINE_ID = pl.PO_LINE_ID(+) and pl.ITEM_ID = item.INVENTORY_ITEM_ID(+) and item.ORGANIZATION_ID(+) = po_lines_sv4.get_inventory_orgid(pl.ORG_ID) and d.INVOICE_ID = rec_schedule.invoice_id and nvl(pd.PROJECT_ID, 0) = nvl(l.project_id, 0)) aa, CUX_AP_ITEM_CATE cc where aa.rnum = 1 and cc.big_code = substr(aa.SEGMENT1, 1, 2); exception when others then lr_ex_info.extra1 := '服务采购'; end; select (extract(year from sysdate) - extract(year from lr_ex_info.gl_date)) * 12 + (extract(month from sysdate) - extract(month from lr_ex_info.gl_date)) into ln_bill_months from dual; if ln_bill_months <= 0 then lr_ex_info.extra2 := '当月结算'; else lr_ex_info.extra2 := '月结' || 30 * ln_bill_months || '天'; end if; begin select c.payment_name, c.payment_name || '-' || c.payment_days, c.term_total, c.line_credit, c.payment_days into lr_ex_info.extra3, lr_ex_info.extra4, lr_ex_info.extra6, lr_ex_info.extra7, ln_pay_months from ap_suppliers t, CUX_AP_LINE_CREDIT c where t.SEGMENT1 = c.segment1 and t.VENDOR_ID = rec_schedule.vendor_id and c.ORG_ID = p_org_id; exception when others then lr_ex_info.extra3 := '现结'; lr_ex_info.extra4 := '现结'; lr_ex_info.extra6 := '现结'; ln_pay_months := 0; end; if ln_bill_months + ln_pay_months <= 0 then lr_ex_info.extra5 := '当月结算'; else lr_ex_info.extra5 := '月结' || (30 * ln_bill_months + ln_pay_months)|| '天'; end if; SCUX_CST_INVEST_REPORT_PKG.get_project_info2(l.project_id, null, lv_pro_attr1, lv_pro_attr2, lv_pro_attr3, lv_pro_attr4, lv_pro_attr5, lv_pro_class, lv_pro_class2); lr_ex_info.proj_big_cate := lv_pro_class2; lr_ex_info.proj_cate := lv_pro_class; lr_ex_info.proj_attr3 := lv_pro_attr3; lr_ex_info.prod_line := lv_pro_attr2; lr_ex_info.cu := l.CU; if P_save='Y' then --delete from cux_ap_schd_extra_t; insert into cux_ap_schd_extra_t values lr_ex_info; end if; cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || lv_pro_attr2 || v_sep || l.CU || v_sep || l.pro_num || v_sep || l.pro_name || v_sep || lv_pro_class2 || v_sep || lv_pro_class || v_sep || lv_pro_attr3 || v_sep || rec_schedule.invoice_amount * l.pro_rate || v_sep || rec_schedule.invoice_amount_b * l.pro_rate || v_sep || rec_schedule.amount_remaining * l.pro_rate || v_sep || rec_schedule.amount_remaining_b * l.pro_rate || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep || l.agent_name || v_sep || l.kb || v_sep || lr_ex_info.extra8 || v_sep || lr_ex_info.extra1 || v_sep || lr_ex_info.extra2 || v_sep || lr_ex_info.extra3 || v_sep || lr_ex_info.extra4 || v_sep || lr_ex_info.extra5 || v_sep || lr_ex_info.extra6 || v_sep || lr_ex_info.extra7 || v_sep || l_extra9 || v_sep || l_extra10 || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); end loop; end loop; end if; END; END cux_ap_schedule_pkg2;
08-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值