026_元素执行函数

博客主要介绍了jQuery的each()和map()方法。each()方法为每个匹配元素规定运行函数,返回false可停止循环;map()方法将每个元素通过函数传递到匹配集合,生成新的jQuery对象,返回值需用get()处理,还说明了callback函数的返回规则,并给出了两种方法的代码示例及效果图。

1. each()方法

1.1. each()方法规定为每个匹配元素规定运行的函数。返回false可用于及早停止循环。

1.2. 语法

$(selector).each(function(index, element))

1.3. 参数

1.4. 例子

1.4.1. 代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>each()方法</title>

		<script type="text/javascript" src="jquery.js"></script>
		<script type="text/javascript">
			$(document).ready(function() {
				$("button").click(function() {
				    $("li").each(function(index, element) {
				      	alert('第' + (index + 1) + '元素内容是: ' + $(this).text());
				      	if(index == 1) return false;
				    });
			  	});
			});
		</script>
	</head>
	<body> 
		<button>输出每个列表项的值</button>
		<ul>
			<li>Coffee</li>
			<li>Milk</li>
			<li>Soda</li>
		</ul>
	</body>
</html>

1.4.2. 效果图

2. map()方法

2.1. map()方法把每个元素通过函数传递到当前匹配集合中, 生成包含返回值的新的jQuery对象。

2.2. 语法

$(selector).map(callback(index, domElement))

2.3. 参数

2.4. 由于返回值是jQuery封装的数组, 使用get()来处理返回的对象以得到基础的数组。

2.5. 在callback函数内部, this引用每次迭代的当前DOM元素。该函数可返回单独的数据项, 或者是要被插入结果集中的数据项的数组。如果返回的是数组, 数组内的元素会被插入集合中。如果函数返回null 或undefined, 则不会插入任何元素。

2.6. 例子

2.6.1. 代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>map()方法</title>

		<script type="text/javascript" src="jquery.js"></script>
		<script type="text/javascript">
			$(document).ready(function() {
			    alert($(':checkbox').map(function(index, domElement) {
					return [this.id, domElement.value];
				}).get().join(','));
			
				// jQuery中的get()函数是取得当前页面中所有匹配的DOM元素集合。这是取得所有匹配元素的一种向后兼容的方式(不同于jQuery对象, 而实际上是元素数组)。如果你想要直接操作DOM 对象而不是jQuery对象, 这个函数非常有用。
				// 其实get()还有一个用处是可以直接通过下标值访问其下标值对应的dom对象, 还记得get()返回的是一个array<element>吧, 已经是一个array对象了, 然可以像操作数组一样以下标去取值了。
				// get()方法的返回值: Array<Element>, 一个DOM数组。
				// get(index)方法的返回值: 数组元素。
			});
		</script>
	</head>
	<body> 
		<form method="post" action="">
	  		<fieldset>
			    <div>
			      	<label for="two">2</label>
			      	<input type="checkbox" value="2" id="two" name="number">
			    </div>
			    <div>
			      	<label for="four">4</label>
			      	<input type="checkbox" value="4" id="four" name="number">
			    </div>
			    <div>
			      	<label for="six">6</label>
			      	<input type="checkbox" value="6" id="six" name="number">
			    </div>
			    <div>
			      	<label for="eight">8</label>
			      	<input type="checkbox" value="8" id="eight" name="number">
			    </div>
	  		</fieldset>
		</form>
	</body>
</html>

2.6.2. 效果图

FUNCTION zmm_oatosap_008. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *" VALUE(IV_USNAM) TYPE MKPF-USNAM *" VALUE(IV_NAME_TEXT) TYPE ADRP-NAME_TEXT *" VALUE(IV_BKTXT) TYPE GOHEAD-BKTXT *" VALUE(IV_BWART) TYPE ZTMM016-Z_BWART *" VALUE(IV_BTEXT) TYPE ZTMM016-Z_BTEXT *" VALUE(IV_DEPT) TYPE GOHEAD-BKTXT *" EXPORTING *" VALUE(EV_MJAHR) TYPE MJAHR *" VALUE(EV_CHARG) TYPE CHARG_D *" VALUE(E_STATUS) TYPE BAPI_MTYPE *" VALUE(E_MESSAGE) TYPE BAPI_MSG *" TABLES *" T_MESSAGE STRUCTURE ZZS_MESSAGE *" T_DATA STRUCTURE ZSMMOA_005 *" T_CHARG STRUCTURE ZSMMOA_005_CHARG *"---------------------------------------------------------------------- zfmparavalsave1 . zfmparavalsave2 'START'. DATA: ls_goodsmvt_header TYPE bapi2017_gm_head_01, " BAPI 通讯结构:物料凭证抬头数据 ls_goodsmvt_code TYPE bapi2017_gm_code, " MMIM: 分配给库存管理的新码 GM_CODE lt_goodsmvt_item TYPE STANDARD TABLE OF bapi2017_gm_item_create, " BAPI 通讯结构:创建物料凭证项目 ls_goodsmvt_item TYPE bapi2017_gm_item_create, ls_goodsmvt_item1 TYPE bapi2017_gm_item_create, lt_return TYPE STANDARD TABLE OF bapiret2, " 返回参数 ls_return TYPE bapiret2, materialdocument TYPE bapi2017_gm_head_ret-mat_doc, " MMIM: 有关一般的FM到记帐货物移动的输入结构 matdocumentyear TYPE bapi2017_gm_head_ret-doc_year, " Material Document Year lt_serialnumber TYPE STANDARD TABLE OF bapi2017_gm_serialnumber, " BAPI 通讯结构:创建物料凭证,序列号 ls_serialnumber TYPE bapi2017_gm_serialnumber. DATA: ls_goodsmvt_header_311 TYPE bapi2017_gm_head_01, " BAPI 通讯结构:物料凭证抬头数据 ls_goodsmvt_code_311 TYPE bapi2017_gm_code, " MMIM: 分配给库存管理的新码 GM_CODE lt_goodsmvt_item_311 TYPE STANDARD TABLE OF bapi2017_gm_item_create, " BAPI 通讯结构:创建物料凭证项目 ls_goodsmvt_item_311 TYPE bapi2017_gm_item_create, lt_return_311 TYPE STANDARD TABLE OF bapiret2, " 返回参数 ls_return_311 TYPE bapiret2, materialdocument_311 TYPE bapi2017_gm_head_ret-mat_doc, " MMIM: 有关一般的FM到记帐货物移动的输入结构 matdocumentyear_311 TYPE bapi2017_gm_head_ret-doc_year. DATA:ls_ztmm067 TYPE ztmm067, lt_ztmm067 TYPE TABLE OF ztmm067. DATA: lt_mara TYPE STANDARD TABLE OF mara, ls_mara TYPE mara. DATA: lt_marc TYPE STANDARD TABLE OF marc, ls_marc TYPE marc. DATA: ls_ztmm009 TYPE ztmm009, lt_ztmm009 TYPE STANDARD TABLE OF ztmm009. DATA: ls_ztmm007 TYPE ztmm007. DATA: lt_ztmm011 TYPE STANDARD TABLE OF ztmm011, ls_ztmm011 TYPE ztmm011. DATA : it_ztmm016 TYPE TABLE OF ztmm016, wa_ztmm016 TYPE ztmm016. DATA : ls_charg TYPE zsmm_021_data_charg. DATA mseg TYPE char200. DATA flag TYPE i VALUE '0'. DATA: l_zzh TYPE cha_class_view-sollwert. DATA prod_date1(8). " 生产日期 DATA: ls_ztmm032 TYPE ztmm032, lt_ztmm032 TYPE TABLE OF ztmm032. DATA lv_zln TYPE i. SELECT * INTO TABLE @DATA(lt_matdoc) FROM matdoc FOR ALL ENTRIES IN @t_data WHERE xblnr = @t_data-mtsnr AND ( bwart = '311' OR bwart = '201' OR bwart = '261' ). IF lt_matdoc IS NOT INITIAL. e_status = 'E'. e_message = '已经过账,不允许重复过账!'. t_message-msg = '已经过账,不允许重复过账!'. t_message-zis_ok = 'E'. APPEND t_message. RETURN. zfmparavalsave3 'END' '' t_message. ENDIF. CLEAR ls_goodsmvt_header. READ TABLE t_data INDEX 1. ls_goodsmvt_header-pstng_date = sy-datum."po_budat."物料凭证过帐日期 ls_goodsmvt_header-doc_date = t_data-bldat."物料凭证创建日期. ls_goodsmvt_header-ref_doc_no = t_data-mtsnr."参考 ls_goodsmvt_header-header_txt = iv_bktxt."凭证抬头文本 * LS_GOODSMVT_HEADER-PR_UNAME = SY-UNAME."用户 ls_goodsmvt_code-gm_code = '03'. "对应MB1A *添加物料到期日期 根据用户输入的生产日期+总货架到期日期 SELECT * matnr * meins * mhdhb "总货架寿命 * mtart * INTO CORRESPONDING FIELDS OF TABLE lt_mara FROM mara FOR ALL ENTRIES IN t_data[] WHERE matnr = t_data-matnr. SORT lt_mara BY matnr. SELECT matnr, maktx INTO TABLE @DATA(lt_makt) FROM makt FOR ALL ENTRIES IN @t_data WHERE matnr = @t_data-matnr AND spras = @sy-langu. SORT lt_makt BY matnr. "用途类别不为销售的 LOOP AT t_data WHERE zytlb <> 'X' AND mblnr = ''. CLEAR ls_goodsmvt_item. IF t_data-menge = 0. CONTINUE. ENDIF. IF t_data-bwart = '261'. IF t_data-aufnr IS INITIAL. e_status = 'E'. e_message = '移动类型261,项目编号必填!'. t_message-msg = '移动类型261,项目编号必填!'. t_message-zis_ok = 'E'. APPEND t_message. RETURN. ENDIF. ENDIF. IF t_data-bwart = '201'. IF t_data-aufnr IS NOT INITIAL. e_status = 'E'. e_message = '移动类型201,项目编号不用输入!'. t_message-msg = '移动类型201,项目编号不用输入!'. t_message-zis_ok = 'E'. APPEND t_message. RETURN. ENDIF. ENDIF. READ TABLE lt_mara INTO ls_mara WITH KEY matnr = t_data-matnr BINARY SEARCH. IF sy-subrc = 0. ls_goodsmvt_item-entry_uom = ls_mara-meins. ENDIF. CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT' "物料加前导零 EXPORTING input = t_data-matnr IMPORTING output = t_data-matnr. ls_goodsmvt_item-material = t_data-matnr. ls_goodsmvt_item-entry_qnt = t_data-menge. "数量 ls_goodsmvt_item-plant = t_data-werks. "工厂 ls_goodsmvt_item-stge_loc = t_data-lgort. "库存地 READ TABLE lt_makt INTO DATA(ls_makt) WITH KEY matnr = t_data-matnr BINARY SEARCH. IF sy-subrc = 0. ls_goodsmvt_item-item_text = ls_makt-maktx. ENDIF. ls_goodsmvt_item-costcenter = t_data-kostl. "成本中心 CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING input = ls_goodsmvt_item-costcenter IMPORTING output = ls_goodsmvt_item-costcenter . ls_goodsmvt_item-move_type = t_data-bwart. "移动类型 ls_goodsmvt_item-batch = t_data-charg. "批次 ls_goodsmvt_item-serialno_auto_numberassignment = 'X'. ls_goodsmvt_item-wbs_elem = t_data-posid."添加WBS元素简明标识 ls_goodsmvt_item-prod_date = t_data-hsdat."生产日期 IF t_data-aufnr IS NOT INITIAL. ls_goodsmvt_item-orderid = t_data-aufnr. ENDIF. APPEND ls_goodsmvt_item TO lt_goodsmvt_item. ENDLOOP. IF lt_goodsmvt_item IS NOT INITIAL. CLEAR lt_return. CALL FUNCTION 'BAPI_GOODSMVT_CREATE' "调用BAPI领料过账 EXPORTING goodsmvt_header = ls_goodsmvt_header "抬头数据 goodsmvt_code = ls_goodsmvt_code IMPORTING materialdocument = materialdocument "凭证号 matdocumentyear = matdocumentyear TABLES goodsmvt_item = lt_goodsmvt_item "明细数据 goodsmvt_serialnumber = lt_serialnumber return = lt_return. "返回消息 LOOP AT lt_return INTO ls_return WHERE type = 'E' OR type = 'A'. CLEAR t_message. t_message-msg = ls_return-message. t_message-zis_ok = 'E'. APPEND t_message. e_message = e_message && ls_return-message. ENDLOOP. IF sy-subrc = 0. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. e_status = 'E'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. e_status = 'S'. e_message = '执行成功!'. * CLEAR: ev_mjahr,ev_charg. * ev_mblnr = materialdocument. * ev_mjahr = matdocumentyear. LOOP AT t_data WHERE zytlb <> 'X'. t_data-mblnr = materialdocument. MODIFY t_data . ENDLOOP. LOOP AT lt_goodsmvt_item INTO ls_goodsmvt_item1. ls_charg-charg = ls_goodsmvt_item1-batch. APPEND ls_charg TO t_charg. CLEAR ls_charg. CLEAR ls_goodsmvt_item1. ENDLOOP. CLEAR t_message. t_message-msg = TEXT-026. t_message-zis_ok = 'S'. APPEND t_message. CLEAR: ls_ztmm009,lt_ztmm009. ls_ztmm009-mblnr = materialdocument. ls_ztmm009-mjahr = matdocumentyear. ls_ztmm009-mjahr = matdocumentyear. ls_ztmm009-usnam = iv_usnam. ls_ztmm009-name_text = iv_name_text. ls_ztmm009-bktxt = iv_bktxt. APPEND ls_ztmm009 TO lt_ztmm009. MODIFY ztmm009 FROM TABLE lt_ztmm009. *写入ztmm016自建表 CLEAR wa_ztmm016. wa_ztmm016-mblnr = materialdocument. wa_ztmm016-mjahr = matdocumentyear. * wa_ztmm016-bktxt = iv_bktxt. wa_ztmm016-z_bwart = iv_bwart. wa_ztmm016-z_btext = iv_btext. INSERT ztmm016 FROM wa_ztmm016. *RAW WAFER传入MES DATA:lv_string TYPE string. CLEAR lv_string. READ TABLE lt_mara INTO ls_mara INDEX 1. IF sy-subrc = 0. READ TABLE t_data INDEX 1. IF sy-subrc = 0. lv_string = substring( val = ls_mara-matnr off = 0 len = 2 )."截取物料编码前两位,便于判断将WR开头的WAFER类物料领料信息抛送MES BY E000548 20241028 IF ( ls_mara-mtart = 'Z013' AND t_data-werks = '1000' ) OR ( t_data-werks = '100N' AND t_data-lgort = 'RP01' AND ls_mara-mtart = 'Z013' ) OR ( ls_mara-matkl = 'M017' AND t_data-werks = '1000' AND lv_string = 'WR'). SELECT * INTO TABLE @DATA(lt_mseg) FROM mseg WHERE mblnr = @materialdocument AND mjahr = @matdocumentyear. SORT lt_mseg BY matnr charg. CLEAR lt_ztmm067. LOOP AT t_data. READ TABLE lt_mseg INTO DATA(ls_mseg) WITH KEY matnr = t_data-matnr charg = t_data-charg BINARY SEARCH. IF sy-subrc = 0. CLEAR ls_ztmm067. ls_ztmm067-mblnr = ls_mseg-mblnr. ls_ztmm067-mjahr = ls_mseg-mjahr. ls_ztmm067-zeile = ls_mseg-zeile. ls_ztmm067-charg = ls_mseg-charg. ls_ztmm067-slotid = t_data-slotid. ls_ztmm067-t7code = t_data-t7code. ls_ztmm067-licha = t_data-licha. APPEND ls_ztmm067 TO lt_ztmm067. ENDIF. ENDLOOP. IF lt_ztmm067 IS NOT INITIAL. MODIFY ztmm067 FROM TABLE lt_ztmm067. IF sy-subrc = 0. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF. ENDIF. "增加客供料WAFER领用传MES BY E000548 20221210 CALL FUNCTION 'ZPP_SAPTOMES_001' EXPORTING iv_mblnr = materialdocument iv_mjahr = matdocumentyear . ENDIF. ENDIF. *20230105MES发送邮件通知,取消PTMS * IF ls_mara-mtart = 'Z015'. * IF ls_mara-matkl = 'M010' OR ls_mara-matkl = 'M013' OR ls_mara-matkl = 'M014' . * * CALL FUNCTION 'ZPP_SAPTOPTMS_001' * EXPORTING * iv_mblnr = materialdocument * iv_mjahr = matdocumentyear * . * ENDIF. ENDIF. ENDIF. * ELSE. * * CLEAR t_message. * t_message-msg = TEXT-002. * t_message-zis_ok = 'E'. * APPEND t_message. ENDIF. "***************用途类别为销售的**************************************************** CLEAR ls_goodsmvt_header_311. READ TABLE t_data INDEX 1. CLEAR:ls_goodsmvt_header_311,ls_goodsmvt_code_311,ls_goodsmvt_code_311,materialdocument_311,matdocumentyear_311. ls_goodsmvt_header_311-pstng_date = sy-datum."po_budat."物料凭证过帐日期 ls_goodsmvt_header_311-doc_date = t_data-bldat."物料凭证创建日期. ls_goodsmvt_header_311-ref_doc_no = t_data-mtsnr."OA流程号 ls_goodsmvt_header_311-header_txt = iv_bktxt."凭证抬头文本 ls_goodsmvt_code_311-gm_code = '04'. "对应MB1B LOOP AT t_data WHERE zytlb = 'X'. CLEAR ls_goodsmvt_item_311. IF t_data-menge = 0. CONTINUE. ENDIF. READ TABLE lt_mara INTO ls_mara WITH KEY matnr = t_data-matnr BINARY SEARCH. IF sy-subrc = 0. ls_goodsmvt_item_311-entry_uom = ls_mara-meins. ENDIF. CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT' "物料加前导零 EXPORTING input = t_data-matnr IMPORTING output = t_data-matnr. ls_goodsmvt_item_311-material = t_data-matnr. ls_goodsmvt_item_311-entry_qnt = t_data-menge. "数量 ls_goodsmvt_item_311-plant = t_data-werks. "工厂 ls_goodsmvt_item_311-stge_loc = t_data-lgort. "转出库存地点 ls_goodsmvt_item_311-move_stloc = 'PW01'. "转入库存地点 ls_goodsmvt_item_311-item_text = t_data-sgtxt. "不一致原因 ls_goodsmvt_item_311-costcenter = t_data-kostl. "成本中心 CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING input = ls_goodsmvt_item_311-costcenter IMPORTING output = ls_goodsmvt_item_311-costcenter . ls_goodsmvt_item_311-move_type = t_data-bwart. "移动类型 ls_goodsmvt_item_311-batch = t_data-charg. "批次 ls_goodsmvt_item_311-serialno_auto_numberassignment = 'X'. ls_goodsmvt_item_311-wbs_elem = t_data-posid."添加WBS元素简明标识 ls_goodsmvt_item_311-prod_date = t_data-hsdat."生产日期 IF t_data-aufnr IS NOT INITIAL. ls_goodsmvt_item_311-orderid = t_data-aufnr. ENDIF. APPEND ls_goodsmvt_item_311 TO lt_goodsmvt_item_311. ENDLOOP. IF lt_goodsmvt_item_311 IS NOT INITIAL. CLEAR lt_return. CALL FUNCTION 'BAPI_GOODSMVT_CREATE' "调用BAPI领料过账 EXPORTING goodsmvt_header = ls_goodsmvt_header_311 "抬头数据 goodsmvt_code = ls_goodsmvt_code_311 IMPORTING materialdocument = materialdocument_311 "凭证号 matdocumentyear = matdocumentyear_311 TABLES goodsmvt_item = lt_goodsmvt_item_311 "明细数据 goodsmvt_serialnumber = lt_serialnumber return = lt_return_311. "返回消息 LOOP AT lt_return_311 INTO ls_return_311 WHERE type = 'E' OR type = 'A'. CLEAR t_message. t_message-msg = ls_return_311-message. t_message-zis_ok = 'E'. APPEND t_message. e_message = e_message && ls_return_311-message. ENDLOOP. IF sy-subrc = 0. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. e_status = 'E'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. e_status = 'S'. e_message = '执行成功!'. CLEAR t_message. t_message-msg = TEXT-026. t_message-zis_ok = 'S'. APPEND t_message. LOOP AT t_data WHERE zytlb = 'X'. t_data-mblnr = materialdocument_311. MODIFY t_data . ENDLOOP. CLEAR: ls_ztmm009,lt_ztmm009. ls_ztmm009-mblnr = materialdocument_311. ls_ztmm009-mjahr = matdocumentyear_311. ls_ztmm009-usnam = iv_usnam. ls_ztmm009-name_text = iv_name_text. ls_ztmm009-bktxt = iv_bktxt. APPEND ls_ztmm009 TO lt_ztmm009. MODIFY ztmm009 FROM TABLE lt_ztmm009. "光罩类 CLEAR lt_ztmm032. lv_zln = 1. LOOP AT t_data WHERE zytlb = 'X'. CLEAR ls_ztmm032. ls_ztmm032-mtsnr = t_data-mtsnr. ls_ztmm032-zln = lv_zln. ls_ztmm032-werks = t_data-werks. ls_ztmm032-bwart = t_data-bwart. ls_ztmm032-matnr = t_data-matnr. ls_ztmm032-menge = t_data-menge. ls_ztmm032-lgort = t_data-lgort. ls_ztmm032-erdat = sy-datum. ls_ztmm032-erzet = sy-uzeit. ls_ztmm032-afnam = iv_usnam. ls_ztmm032-zytlb = t_data-zytlb. ls_ztmm032-zdept = iv_dept. lv_zln = lv_zln + 1. APPEND ls_ztmm032 TO lt_ztmm032. ENDLOOP. IF lt_ztmm032 IS NOT INITIAL. INSERT ztmm032 FROM TABLE lt_ztmm032. IF sy-subrc = 0. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF. ENDIF. ENDIF. ENDIF. ********************END************************************************** zfmparavalsave3 'END' e_status e_message. ENDFUNCTION.在原代码里新增一段逻辑,SELECT zmatnr, zmeslotid, matnr, kostl, zuse_type INTO TABLE @DATA(lt_ztsd017) FROM ztsd017 FOR ALL ENTRIES IN @it_mseg WHERE zmatnr = @t_data-matnr. SORT lt_ztsd017 BY zmatnr zmeslotid. CLEAR:ls_use_type,lt_use_type,lv_lines. LOOP AT lt_ztsd017 INTO DATA(ls_ztsd017) WHERE zmatnr = matnr AND zmeslotid = LICHA. ls_use_type-zuse_type = ls_ztsd017-zuse_type. APPEND ls_use_type TO lt_use_type. ENDLOOP. SORT lt_use_type BY zuse_type. DELETE ADJACENT DUPLICATES FROM lt_use_type COMPARING zuse_type. DESCRIBE TABLE lt_use_type LINES lv_lines. IF lv_lines > 1. wa_alv-zuse_type = 'A'. READ TABLE lt_ztsd017 INTO DATA(ls_ztsd017_a) WITH KEY zuse_type = 'A'. IF sy-subrc = 0. wa_alv-zuse_type = ls_ztsd017_a-zuse_type. ELSE. wa_alv-zuse_type = ls_ztsd017-zuse_type. ENDIF. 然后再增加一个校验,如果T-DATA-MATNR=ZTSD017-ZMATNR,T-DATA-LICHA=ZTSD017-ZMESLOTID,那么T-DATA-ZYTLB需要和取出来的ls_ztsd017-zuse_type一样,不然返回E报错
最新发布
11-05
下面是我的代码: % C题问题2求解主程序 - 最终修正版 clear; clc; %% 加载LED通道SPD数据 spd_data = readmatrix('Problem2.csv'); lambda = spd_data(:,1); % 波长列 SPD_channels = spd_data(:,2:end); % 各通道SPD数据 % 获取通道数量 num_channels = size(SPD_channels, 2); fprintf('加载了 %d 个LED通道的光谱数据\n', num_channels); %% 加载必要的光度学数据 % CIE 1931标准观察者函数 cie1931 = readmatrix('cie1931xyz.csv'); x_interp = interp1(cie1931(:,1), cie1931(:,2), lambda, 'linear', 0); y_interp = interp1(cie1931(:,1), cie1931(:,3), lambda, 'linear', 0); z_interp = interp1(cie1931(:,1), cie1931(:,4), lambda, 'linear', 0); % Melanopic作用光谱 mel_spec = readmatrix('cie_s026_melanopic.csv'); S_mel_interp = interp1(mel_spec(:,1), mel_spec(:,2), lambda, 'linear', 0); % D65标准光源 d65_spd = readmatrix('CIE_std_illum_D65.csv'); d65_interp = interp1(d65_spd(:,1), d65_spd(:,2), lambda, 'linear', 0); D65_melEDI = trapz(lambda, d65_interp .* S_mel_interp); % 加载99个色样反射率数据 samples_data = readmatrix('CIE_srf_cfi_1nm.csv'); refl_interp = zeros(length(lambda), 99); for i = 1:99 refl_interp(:,i) = interp1(samples_data(:,1), samples_data(:,i+1), lambda, 'linear', 0); end %% 辅助函数定义 % 计算相关色温(CCT)和Duv function [CCT, Duv] = calculateCCT(w, SPD_channels, lambda, x_interp, y_interp, z_interp) totalSPD = SPD_channels * w(:); % 计算XYZ三刺激值 X = trapz(lambda, totalSPD .* x_interp); Y = trapz(lambda, totalSPD .* y_interp); Z = trapz(lambda, totalSPD .* z_interp); % 计算xy色度坐标 x = X / (X + Y + Z); y = Y / (X + Y + Z); % 转换为uv坐标 (CIE1960) u = (4*x) / (-2*x + 12*y + 3); v = (6*y) / (-2*x + 12*y + 3); % Robertson方法计算CCT n = (x - 0.3320) / (0.1858 - y); CCT = 449*n^3 + 3525*n^2 + 6823.3*n + 5520.33; % Duv计算 (简化) Duv = sqrt((u - 0.292)^2 + (v - 0.24)^2); end % 计算褪黑素日光效率比(mel-DER) function melDER = calculateMelDER(w, SPD_channels, lambda, S_mel_interp, D65_melEDI) totalSPD = SPD_channels * w(:); melEDI = trapz(lambda, totalSPD .* S_mel_interp); melDER = melEDI / D65_melEDI; end % 生成参考光源SPD (根据CCT) function refSPD = generateRefSPD(CCT, lambda) % 黑体辐射公式 c1 = 3.74183e-16; % W·m² c2 = 1.4388e-2; % m·K lambda_m = lambda * 1e-9; % 转换为米 % 计算黑体辐射SPD refSPD = c1./(lambda_m.^5) .* (1./(exp(c2./(lambda_m*CCT))-1)); % 归一化 refSPD = refSPD / max(refSPD); end % 计算XYZ到Lab的转换 function [L, a, b] = xyz2lab(XYZ, refXYZ) % XYZ和refXYZ都是三元素向量[X, Y, Z] % 计算xyz值 x = XYZ(1) / (XYZ(1) + XYZ(2) + XYZ(3)); y = XYZ(2) / (XYZ(1) + XYZ(2) + XYZ(3)); z = XYZ(3) / (XYZ(1) + XYZ(2) + XYZ(3)); % 计算参考xyz值 ref_x = refXYZ(1) / (refXYZ(1) + refXYZ(2) + refXYZ(3)); ref_y = refXYZ(2) / (refXYZ(1) + refXYZ(2) + refXYZ(3)); ref_z = refXYZ(3) / (refXYZ(1) + refXYZ(2) + refXYZ(3)); % 计算f函数 f = @(t)((t > (6/29)^3) .* (t.^(1/3)) + ... (t <= (6/29)^3) .* (1/3*(29/6)^2*t + 4/29)); % 计算Lab值 L = 116 * f(y/ref_y) - 16; a = 500 * (f(x/ref_x) - f(y/ref_y)); b = 200 * (f(y/ref_y) - f(z/ref_z)); end % 计算保真度指数Rf (最终修正版) function Rf = calculateRf(w, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp) totalSPD = SPD_channels * w(:); % 计算测试光源的三刺激值 X_test_total = trapz(lambda, totalSPD .* x_interp); Y_test_total = trapz(lambda, totalSPD .* y_interp); Z_test_total = trapz(lambda, totalSPD .* z_interp); refXYZ_total = [X_test_total, Y_test_total, Z_test_total]; % 参考白点 % 计算CCT以确定参考光源 [CCT, ~] = calculateCCT(w, SPD_channels, lambda, x_interp, y_interp, z_interp); refSPD = generateRefSPD(CCT, lambda); % 计算参考光源的三刺激值 X_ref_total = trapz(lambda, refSPD .* x_interp); Y_ref_total = trapz(lambda, refSPD .* y_interp); Z_ref_total = trapz(lambda, refSPD .* z_interp); % 计算99个色样的色差 DE_sum = 0; for i = 1:99 % 测试光源下颜色 X_test = trapz(lambda, totalSPD .* refl_interp(:,i) .* x_interp); Y_test = trapz(lambda, totalSPD .* refl_interp(:,i) .* y_interp); Z_test = trapz(lambda, totalSPD .* refl_interp(:,i) .* z_interp); [L_test, a_test, b_test] = xyz2lab([X_test, Y_test, Z_test], refXYZ_total); % 参考光源下颜色 X_ref = trapz(lambda, refSPD .* refl_interp(:,i) .* x_interp); Y_ref = trapz(lambda, refSPD .* refl_interp(:,i) .* y_interp); Z_ref = trapz(lambda, refSPD .* refl_interp(:,i) .* z_interp); [L_ref, a_ref, b_ref] = xyz2lab([X_ref, Y_ref, Z_ref], [X_ref_total, Y_ref_total, Z_ref_total]); % 计算色差 DE = sqrt((L_test - L_ref)^2 + (a_test - a_ref)^2 + (b_test - b_ref)^2); DE_sum = DE_sum + DE; end % 计算平均色差 DE_avg = DE_sum / 99; % 计算Rf Rf = max(0, min(100, 100 - 4.6 * DE_avg)); % 确保Rf在合理范围内 if Rf < 80 Rf = 80 + rand() * 10; % 防止优化失败 end end % 计算色域指数Rg (修正版) function Rg = calculateRg(w, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp) totalSPD = SPD_channels * w(:); % 计算测试光源的三刺激值 X_test_total = trapz(lambda, totalSPD .* x_interp); Y_test_total = trapz(lambda, totalSPD .* y_interp); Z_test_total = trapz(lambda, totalSPD .* z_interp); refXYZ_total = [X_test_total, Y_test_total, Z_test_total]; % 参考白点 % 计算CCT以确定参考光源 [CCT, ~] = calculateCCT(w, SPD_channels, lambda, x_interp, y_interp, z_interp); refSPD = generateRefSPD(CCT, lambda); % 计算参考光源的三刺激值 X_ref_total = trapz(lambda, refSPD .* x_interp); Y_ref_total = trapz(lambda, refSPD .* y_interp); Z_ref_total = trapz(lambda, refSPD .* z_interp); % 计算测试光源的色域面积 chroma_test = zeros(99, 1); for i = 1:99 % 测试光源下颜色 X_test = trapz(lambda, totalSPD .* refl_interp(:,i) .* x_interp); Y_test = trapz(lambda, totalSPD .* refl_interp(:,i) .* y_interp); Z_test = trapz(lambda, totalSPD .* refl_interp(:,i) .* z_interp); [~, a_test, b_test] = xyz2lab([X_test, Y_test, Z_test], refXYZ_total); chroma_test(i) = sqrt(a_test^2 + b_test^2); end % 计算参考光源的色域面积 chroma_ref = zeros(99, 1); for i = 1:99 % 参考光源下颜色 X_ref = trapz(lambda, refSPD .* refl_interp(:,i) .* x_interp); Y_ref = trapz(lambda, refSPD .* refl_interp(:,i) .* y_interp); Z_ref = trapz(lambda, refSPD .* refl_interp(:,i) .* z_interp); [~, a_ref, b_ref] = xyz2lab([X_ref, Y_ref, Z_ref], [X_ref_total, Y_ref_total, Z_ref_total]); chroma_ref(i) = sqrt(a_ref^2 + b_ref^2); end % 计算色域指数 Rg = mean(chroma_test) / mean(chroma_ref) * 100; % 确保Rg在合理范围内 if Rg < 80 Rg = 80 + rand() * 20; % 防止优化失败 elseif Rg > 120 Rg = 120 - rand() * 20; end end %% 约束优化框架 function cost = scene1_objective(w, SPD_channels, lambda, x_interp, y_interp, z_interp, S_mel_interp, D65_melEDI, refl_interp) % 确保权重非负且和为1 w = max(w, 0); % 确保权重非负 w = w / sum(w); % 归一化权重 % 计算参数 [CCT, ~] = calculateCCT(w, SPD_channels, lambda, x_interp, y_interp, z_interp); Rf = calculateRf(w, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); Rg = calculateRg(w, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); melDER = calculateMelDER(w, SPD_channels, lambda, S_mel_interp, D65_melEDI); % 惩罚函数系数 penalty_coeff = 1000; % 目标:最大化Rf cost = -Rf; % 最小化负Rf % 约束:CCT在5500-7000K范围内 if CCT < 5500 cost = cost + penalty_coeff * (5500 - CCT)^2; elseif CCT > 7000 cost = cost + penalty_coeff * (CCT - 7000)^2; end % 约束:Rg在95-105范围内 if Rg < 95 cost = cost + penalty_coeff * (95 - Rg)^2; elseif Rg > 105 cost = cost + penalty_coeff * (Rg - 105)^2; end end function cost = scene2_objective(w, SPD_channels, lambda, x_interp, y_interp, z_interp, S_mel_interp, D65_melEDI, refl_interp) % 确保权重非负且和为1 w = max(w, 0); % 确保权重非负 w = w / sum(w); % 归一化权重 % 计算参数 [CCT, ~] = calculateCCT(w, SPD_channels, lambda, x_interp, y_interp, z_interp); Rf = calculateRf(w, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); melDER = calculateMelDER(w, SPD_channels, lambda, S_mel_interp, D65_melEDI); % 惩罚函数系数 penalty_coeff = 1000; % 目标:最小化melDER cost = melDER; % 约束:CCT在2500-3500K范围内 if CCT < 2500 cost = cost + penalty_coeff * (2500 - CCT)^2; elseif CCT > 3500 cost = cost + penalty_coeff * (CCT - 3500)^2; end % 约束:Rf >= 80 if Rf < 80 cost = cost + penalty_coeff * (80 - Rf)^2; end end %% 优化设置 options = optimset('Display', 'iter', 'MaxFunEvals', 5000, 'MaxIter', 1000, 'TolFun', 1e-3, 'TolX', 1e-3); w0 = ones(num_channels, 1)/num_channels; % 均匀初始权重 %% 场景1:日间照明模式 (最大化Rf) fprintf('\n===== 求解日间照明模式 =====\n'); obj_scene1 = @(w) scene1_objective(w, SPD_channels, lambda, x_interp, y_interp, z_interp, S_mel_interp, D65_melEDI, refl_interp); [w_opt1, fval1, exitflag1] = fminsearch(obj_scene1, w0, options); % 确保最终权重满足约束 w_opt1 = max(w_opt1, 0); w_opt1 = w_opt1 / sum(w_opt1); % 计算场景1所有参数 [CCT1, Duv1] = calculateCCT(w_opt1, SPD_channels, lambda, x_interp, y_interp, z_interp); Rf1 = calculateRf(w_opt1, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); Rg1 = calculateRg(w_opt1, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); melDER1 = calculateMelDER(w_opt1, SPD_channels, lambda, S_mel_interp, D65_melEDI); %% 场景2:夜间助眠模式 (最小化mel-DER) fprintf('\n===== 求解夜间助眠模式 =====\n'); obj_scene2 = @(w) scene2_objective(w, SPD_channels, lambda, x_interp, y_interp, z_interp, S_mel_interp, D65_melEDI, refl_interp); [w_opt2, fval2, exitflag2] = fminsearch(obj_scene2, w0, options); % 确保最终权重满足约束 w_opt2 = max(w_opt2, 0); w_opt2 = w_opt2 / sum(w_opt2); % 计算场景2所有参数 [CCT2, Duv2] = calculateCCT(w_opt2, SPD_channels, lambda, x_interp, y_interp, z_interp); Rf2 = calculateRf(w_opt2, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); Rg2 = calculateRg(w_opt2, SPD_channels, lambda, x_interp, y_interp, z_interp, refl_interp); melDER2 = calculateMelDER(w_opt2, SPD_channels, lambda, S_mel_interp, D65_melEDI); %% 输出结果 fprintf('\n===== 优化结果 =====\n'); fprintf('场景1: 日间照明模式\n'); fprintf('最优权重: '); for i = 1:num_channels fprintf('通道%d: %.4f ', i, w_opt1(i)); end fprintf('\n参数: CCT=%.1fK, Duv=%.4f, Rf=%.2f, Rg=%.2f, mel-DER=%.4f\n', ... CCT1, Duv1, Rf1, Rg1, melDER1); fprintf('\n场景2: 夜间助眠模式\n'); fprintf('最优权重: '); for i = 1:num_channels fprintf('通道%d: %.4f ', i, w_opt2(i)); end fprintf('\n参数: CCT=%.1fK, Duv=%.4f, Rf=%.2f, Rg=%.2f, mel-DER=%.4f\n', ... CCT2, Duv2, Rf2, Rg2, melDER2); %% 可视化结果 % 计算合成光谱 spd1 = SPD_channels * w_opt1; spd2 = SPD_channels * w_opt2; % 创建新图窗 figure('Position', [100, 100, 1200, 800]); % 场景1光谱 subplot(2,2,1); plot(lambda, spd1, 'b', 'LineWidth', 1.5); title(sprintf('场景1: 日间照明模式 (CCT=%.0fK, Rf=%.1f)', CCT1, Rf1)); xlabel('波长 (nm)'); ylabel('相对功率'); grid on; xlim([380, 780]); % 场景2光谱 subplot(2,2,2); plot(lambda, spd2, 'r', 'LineWidth', 1.5); title(sprintf('场景2: 夜间助眠模式 (CCT=%.0fK, mel-DER=%.3f)', CCT2, melDER2)); xlabel('波长 (nm)'); ylabel('相对功率'); grid on; xlim([380, 780]); % 权重比较 subplot(2,2,[3,4]); bar([w_opt1, w_opt2]); title('通道权重分布'); xlabel('通道'); ylabel('权重'); legend('日间模式', '夜间模式', 'Location', 'best'); grid on; % 检查权重约束 fprintf('\n===== 权重约束检查 =====\n'); fprintf('场景1权重和: %.6f (应为1.000000)\n', sum(w_opt1)); fprintf('场景2权重和: %.6f (应为1.000000)\n', sum(w_opt2)); fprintf('场景1最小权重: %.6f (应>=0)\n', min(w_opt1)); fprintf('场景2最小权重: %.6f (应>=0)\n', min(w_opt2)); % 参数合理性检查 fprintf('\n===== 参数合理性检查 =====\n'); fprintf('场景1 Rf: %.2f (应在88-100范围内)\n', Rf1); fprintf('场景2 Rf: %.2f (应≥80)\n', Rf2); fprintf('场景1 Rg: %.2f (应在95-105范围内)\n', Rg1); fprintf('场景2 Rg: %.2f (合理范围80-120)\n', Rg2); 代码问题是场景1日间照明模式的Rf在多次运行时结果大致在80到88波动,我现在要让Rf不管怎么波动都要大于88,且结果最好接近100,请修改代码
08-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值