#include "StdAfx.h" #include "WorkRecord.h" #include "Propertie.h" #include "PropertieMgr.h" #include "AuthorityMgr.h" #include "WorkTime.h" #include "FileMgr.h" #include "LogMgr.h" #include "GlobalFunction.h" #include "WorkFileMgr.h" #include "CStringFuc.h" #include "ProgramLaserTuiHuo.h" #include "AllThreadMgr.h" #include "WaferRecipeDataMgr.h" #include "RecipeMgr.h" #include "Layer.h" #include "Laser.h" #include "MsgBox.h" #include "MyDlgView.h" #include "TimingProgressMgr.h" #include "ObjFillMgr.h" #define RECORD_FILE_PATH _T("\\WorkRecord") #define RECOR_JOB_ID "Job ID" #define RECOR_LOT_ID "Lot ID" #define RECOR_RECIPE "Recipe" #define RECOR_LAYER_IDX "编号" #define RECOR_START_TIME "开始时间" #define RECOR_SPAN_TIME "加工时间" #define RECOR_SPAN_TIME_S "加工时间(秒)" #define RECOR_SPAN_USER_NAME "用户名" #define RECOR_SPAN_USER_TYPE "用户类型" #define RECOR_SPAN_START_SCAN_IDX "开始索引值" #define RECOR_SPAN_END_SCAN_IDX "结束索引值" #define RECOR_SPAN_TOTAL_SCAN_IDX "扫描线总数" #define RECOR_FOCUS_Z_COORD "激光焦点位置" //退火时Z 轴的坐标值(每片wafer 可能会有点不一样) #define RECOR_DISMETER_OFFSET "测距偏移值"//记录了当前焦点的情况 #define RECOR_LASER_SPOT_W "光斑宽度" #define RECOR_LASER_SPOT_H "光斑高度" #define RECOR_SET_LASER1_CURR "设定激光1 电流" #define RECOR_SET_LASER2_CURR "设定激光2 电流" //计时线程(用来通知观察者时间发生变化) UINT RecordTimeThread(LPVOID pParam) { CWorkRecordMgr *p = (CWorkRecordMgr *)pParam; p->UpdateCurRecordTime(); return 0; } CWorkRecordMgr *gWorkRecordMgr = new CWorkRecordMgr; CWorkRecordMgr::CWorkRecordMgr(void) { m_CurProcessingTime = "00:00:00"; m_CurTotalWorkTime = "00:00:00";//当前总的加工时间 m_bSelWorkInfoRecord = false;//是否有选中的记录 } CWorkRecordMgr::~CWorkRecordMgr(void) { } void CWorkRecordMgr::OnAppInitialize() { //启动记录加工时间的线程 CWinThread* pThread; pThread = AfxBeginThread(RecordTimeThread,this); gAllThreadMgr.BindingThreadAdr(_EThreadType_RecordTimeThread,pThread); //检查记录目录是否需要创建 #if 0 CString RecordPath; CFileMgr FileMgr; FileMgr.GetFullFilePath(RecordPath,RECORD_FILE_PATH); if(!FileMgr.IsFileExist(RecordPath)) { FileMgr.CreatDir(RecordPath); } #endif } //刷新当前时间进度 void CWorkRecordMgr::UpdateCurRecordTime() { while(1) { if(gAllThreadMgr.IsbStopAllThread()) break; gAllThreadMgr.SetThreadInfoState(_EThreadType_RecordTimeThread,true); CString SpanStr = m_WorkTime.GetTimeSpanStr(); if(SpanStr !="") { m_CurProcessingTime = SpanStr;//当前加工时间 } Sleep(500); } gAllThreadMgr.SetThreadInfoState(_EThreadType_RecordTimeThread,false); } #if 1 //开始记录 void CWorkRecordMgr::StartRecord() { gLogMgr->WriteDebugLog("Func---->RecordMgr Start Record"); //记录加工开始时间 m_WorkStartTime = m_WorkTime.GetCurTime(":"); m_WorkTime.StartRecordTime(); //记录开始的索引值 CObjContainer &ObjContainer = gLayer.GetObjContainer(); if(_ScanStateType_AllScanned == GetCurScanStateType()) { //重置扫描状态 ResetScanState(); gLayer.ResetAllObjScaned(); } //记录当前扫描线的总数 m_CurScanState.m_TotalScanLineCnt = ObjContainer.GetScanLineCnt(); //记录扫描开始的idx m_CurScanState.m_StartScanLineIdx = m_CurScanState.m_EndScanLineIdx; m_CurScanState.m_ScanedLineCnt = 0; GetCurScanStateType(); } //结束记录 void CWorkRecordMgr::EndRecord() { m_CurScanState.m_EndScanLineIdx = m_CurScanState.m_StartScanLineIdx + m_CurScanState.m_ScanedLineCnt; GetCurScanStateType(); //设置obj 的扫描状态 CObjContainer &ObjContainer = gLayer.GetObjContainer(); ObjContainer.SetObjScanState(m_CurScanState.m_EndScanLineIdx); //至少要扫描一条线段才记录 if(m_CurScanState.m_ScanedLineCnt>1) { //保存当前的加工记录 SaveCurWorkRecord(); } } //停止记录时间 void CWorkRecordMgr::EndRecordTime() { m_WorkTime.StopRecordTime(); double SpanSecond = m_WorkTime.GetTimeSpanSecond();//经过秒数,用来计算OEE m_CurRecordTimeSecond = Db2CString(SpanSecond); } #endif #if 1 //获取当前的扫描状态 EScanStateType CWorkRecordMgr::GetCurScanStateType() { CString str; EScanStateType ScanState; int EndScanLineIdx = m_CurScanState.m_EndScanLineIdx; int TotalScanLineCnt = m_CurScanState.m_TotalScanLineCnt; str.Format("Par---->StartIdx[%ld]Scaned[%ld]EndIdx[%ld]Total[%ld]",m_CurScanState.m_StartScanLineIdx,m_CurScanState.m_ScanedLineCnt,EndScanLineIdx,TotalScanLineCnt); gLogMgr->WriteDebugLog(str); if(EndScanLineIdx==0) { ScanState = _ScanStateType_NotScanned; str = ("CurScanState: _NotScanned"); } else if(EndScanLineIdx>0 && (EndScanLineIdx < (TotalScanLineCnt))) { ScanState = _ScanStateType_PartiallyScanned; str = ("CurScanState: _PartiallyScanned"); } else if(EndScanLineIdx >= (TotalScanLineCnt)) { ScanState = _ScanStateType_AllScanned; str = ("CurScanState: _AllScanned"); } else { ScanState = _ScanStateType_Null; str = ("CurScanState: _Type_Null"); } gLogMgr->WriteDebugLog(str); return ScanState; } //重置扫描状态 void CWorkRecordMgr::ResetScanState() { gLogMgr->WriteDebugLog("Func---->ResetScanState"); m_CurScanState.m_EndScanLineIdx = 0; m_CurScanState.m_ScanedLineCnt = 0; } #endif #if 1 //获取名字为FileName 的记录路径 CString CWorkRecordMgr::GetRecordFilePath(CString FileName) { CString FullFilePath; CString WorkRecordFilePath = gProgramLaserTuiHuo->GetWorkRecordFilePath(); if(WorkRecordFilePath=="") { CString FilePath = RECORD_FILE_PATH; FilePath += "\\" + FileName + ".rcd"; CFileMgr FileMgr; FileMgr.GetFullFilePath(FullFilePath,FilePath); } else { FullFilePath = WorkRecordFilePath+"\\" + FileName + ".rcd"; } return FullFilePath; } //获取当前记录文件的名字(0点到24点算一天) CString CWorkRecordMgr::GetCurRecordFileName() { return m_WorkTime.GetCurDate("_"); } #endif #if 1 //保存当前的加工记录 void CWorkRecordMgr::SaveCurWorkRecord() { gLogMgr->WriteDebugLog("Func---->SaveCurWorkRecord"); CWorkRecord WorkRecord; //创建当前的加工记录 CreatCurWorkRecord(WorkRecord); //加工记录写入到文件 WriteWorkRecordToFile(WorkRecord); //累加CyclicWafer 数量 gProgramLaserTuiHuo->CyclicWaferInc(); } //创建当前的加工记录 void CWorkRecordMgr::CreatCurWorkRecord(CWorkRecord &WorkRecord) { //创建基础信息 CreatBaseInfoRecord(WorkRecord); //创建扫描数据信息 CreatScanDataRecord(WorkRecord); //创建当前Recipe 信息 CreatRecipeRecord(WorkRecord); } //创建基础信息Record void CWorkRecordMgr::CreatBaseInfoRecord(CWorkRecord &WorkRecord) { } //创建扫描数据信息Record (显示在详细列表的内容) void CWorkRecordMgr::CreatScanDataRecord(CWorkRecord &WorkRecord) { } //创建当前Recipe 信息Record void CWorkRecordMgr::CreatRecipeRecord(CWorkRecord &WorkRecord) { CRecipe Recipe = gRecipeMgr->GetCurWorkRecipe(); vector &RecipeParVec = Recipe.GetRecipeParVec(); int size = RecipeParVec.size(); for(int i=0;i>RecordCnt; } } RecordCnt++;//增加记录的数量 //以追加的方式写入文件 { CFile file(RecordFilePath,CFile::modeWrite|CFile::modeNoTruncate|CFile::modeCreate); file.SeekToEnd(); CArchive ar(&file,CArchive::store); if(!bFileExist)//第一次写入 ar<&RecordParVec = WorkRecord.m_RecordParVec; int ParCnt = RecordParVec.size(); ar<>RecordCnt; for(int k=0;k>ParCnt;//参数的数量 for(int i=0;i>RecordPar.m_ParName;//参数名 ar>>RecordPar.m_ParVal;//参数值 Record.AddRecordPar(RecordPar); } //同步ReadWorkRecord 到WorkRecord (避免存储的参数和现在不一致) SynchWorkRecord(WorkRecord,Record); m_ShowRecordVec.push_back(WorkRecord); m_WorkRecordVec.push_back(Record); } } } //同步ReadWorkRecord 到WorkRecord void CWorkRecordMgr::SynchWorkRecord(CWorkRecord &Record,CWorkRecord &ReadRecord) { vector&RecordParVec = Record.m_RecordParVec; vector&ReadRecordParVec = ReadRecord.m_RecordParVec; int ParCnt = RecordParVec.size(); for(int k=0;k &DateVec,CString StartDate,CString EndDate) { vector AllDateVec; CString FullFilePath; CFileMgr FileMgr; CString WorkRecordFilePath = gProgramLaserTuiHuo->GetWorkRecordFilePath(); if(WorkRecordFilePath=="") { CString FilePath = RECORD_FILE_PATH; FilePath += "\\"; FileMgr.GetFullFilePath(FullFilePath,FilePath); } else { FullFilePath = WorkRecordFilePath+"\\"; } FileMgr.GetChildFileOrDirName(false,FullFilePath,AllDateVec,".rcd"); int size = AllDateVec.size(); for(int k=0;k=StartDate && DateStr<=EndDate) DateVec.push_back(DateStr); } } #endif #if 1 //初始化工作记录list void CWorkRecordMgr::InitWorkRecordList(CListCtrl &List) { //设置风格 List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); CWorkRecord WorkRecord; //创建在列表中显示的WorkRecord CreatListShowWorkRecord(WorkRecord); int idx = 0; List.InsertColumn(idx++,"序号",LVCFMT_CENTER,50,-1); vector&RecordParVec = WorkRecord.m_RecordParVec; int ParCnt = RecordParVec.size(); for(int k=0;kWriteDebugLog(log); vector DateVec; GetAllRecordNameVec(DateVec,StartDate,EndDate); int size = DateVec.size(); int MaxWorkRecodCnt = gLogMgr->GetMaxWorkRecodCnt(); if(size>MaxWorkRecodCnt) { CString s; s.Format("查询记录数量%ld 超过限制%ld",size,MaxWorkRecodCnt); CMsgBox MsgBox; MsgBox.Show(s); return; } List.DeleteAllItems(); m_ShowRecordVec.clear(); m_WorkRecordVec.clear(); for(int k=0;k &WorkRecordVec) { int size = WorkRecordVec.size(); for(int i=0;i &RecordParVec = WorkRecordVec[i].m_RecordParVec; int ParCnt = RecordParVec.size(); for(int k=0;k= RecordCnt) return; SetbSelWorkInfoRecord(true); CWorkRecord &WorkRecord = m_WorkInfoRecord; //创建在列表中显示的WorkRecord CreatListWorkInfoRecord(WorkRecord);//只是创建一个空的WorkRecord CWorkRecord &SelRecord = m_WorkRecordVec[Idx]; //将记录中SelRecord 参数值同步到WorkRecord 中 //因为WorkRecord 可能会有新增参数 SynchWorkRecord(WorkRecord,SelRecord); vector &RecordParVec = WorkRecord.m_RecordParVec; int size = RecordParVec.size(); for(int i=0;iWriteDebugLog("Func---->OnBnClickedRecoverFormRcd"); CMsgBox MsgBox; if(gProgramLaserTuiHuo->IsbAutoWorking()) { gLogMgr->WriteDebugLog("加工过程中不能设置!"); return; } if(!gAuthorityMgr->CheckAuthority(_Authority_Engineer,true)) return; if(!m_bSelWorkInfoRecord) { MsgBox.Show("请先选择需要恢复的记录!"); return; } if(!MsgBox.ConfirmOkCancel("从选中记录恢复recipe ?")) return; int EndScanIdx = 0;//扫描结束时的索引 int TotalScanIdx = 0;//扫描线总数 CRecipe RecordRecipe; //从record 中生成recipe vector &RecordParVec = m_WorkInfoRecord.m_RecordParVec; int size = RecordParVec.size(); for(int k=0;k&RecipeParVec = RecordRecipe.GetRecipeParVec(); int size1 = RecipeParVec.size(); for(int i=0;iGetRecoverScanIdxAdjust(); } } gObjFillMgr.SetStartFillIdx(StartFillIdx); CString log; log.Format("EndScanIdx = %d,TotalScanIdx = %d,StartFillIdx = %d",EndScanIdx,TotalScanIdx,StartFillIdx); gLogMgr->WriteDebugLog(log); //重置扫描状态 gWorkRecordMgr->ResetScanState(); //设置当前工作用的recipe gRecipeMgr->SetCurWorkRecipe(RecordRecipe); gObjFillMgr.SetStartFillIdx(0); } //选中的加工记录导出到txt 文件 void CWorkRecordMgr::SelWrokRecordToFile() { gLogMgr->WriteDebugLog("Func---->SelWrokRecordToFile"); CMsgBox MsgBox; if(!gAuthorityMgr->CheckAuthority(_Authority_Engineer,true)) return; int RcdCnt = m_WorkRecordVec.size(); if(RcdCnt<=0) { CMsgBox MsgBox; MsgBox.Show("没有要导出的记录!"); return; } TCHAR szFilters[]=("TXT 文件(*.txt)|*.txt"); CString FileName("WrokRecord_"); FileName += gWorkTime.GetDateTime("_","_"); CFileDialog dlg(FALSE,("txt"),FileName,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilters); CString Path = "E:\\";//默认路径 dlg.m_ofn.lpstrInitialDir = Path; if(dlg.DoModal()==IDOK) { ofstream FileStream; FileStream.open(dlg.GetPathName()); for(int k=0;k &RecordParVec = WorkRecord.m_RecordParVec; int size = RecordParVec.size(); for(int i=0;i