/
ivan
/
ModMas
Обзор
Документация
Войти
/
ivan
/
ModMas
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ModuleMaster/production/pcb_short.aspx.vb
364 строки
21 KB
i.krivokon
Initial commit
13 мар 2026, 13:49
13 мар 2026, 13:49
00d9fb6
Код
Авторство
О чём код?
Imports System.Data Imports System.IO Partial Class capa Inherits System.Web.UI.Page Private collection As New Dictionary(Of Integer, String) Private sqlf As New sharedClasses.dbFunctions.SqlFunctions Public Shared Sub ApplyGridViewHeader(ParentId As String, ByRef gv As GridView, ByRef a As Collection) 'процедура написана таким образом, что в нее всегда должны передаваться индексы с учетом только фактически отображаемых колонок 'т.е. при вычислении индекса объединяемой колонки (передаваемой в качестве параметра в процедуру) считается, 'что колонок со свойством Visible = false в таблице как бы нет. 'индексы (передаваемые в качестве параметров в процедуру) указываются по исходному порядку необъединенных колонок Dim AllowSorting As Boolean = gv.AllowSorting If gv.Rows.Count > 0 Then Dim row = New GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal) Dim r = gv.HeaderRow Dim cell As TableHeaderCell Dim i, j As Integer Dim invisibleColsCount As Integer = 0 Dim cnt As Integer = 0 'i = 1 For Each rcell As TableCell In r.Cells cell = New TableHeaderCell If AllowSorting Then Dim lb As New HyperLink Try lb.Style("color") = "White" lb.Text = CType(rcell.Controls(0), LinkButton).Text lb.NavigateUrl = "javascript:__doPostBack('" & ParentId & "$" & gv.ID & "','Sort$" & CType(rcell.Controls(0), LinkButton).CommandArgument & "')" cell.Controls.Add(lb) Catch ex As Exception cell.Text = rcell.Text End Try Else cell.Text = rcell.Text End If cell.Style("text-align") = "center" cell.Visible = rcell.Visible 'If cnt > a(i)(1) And cnt < a(i)(1) + a(i)(2) Then ' If Not rcell.Visible Then ' invisibleColsCount += 1 ' End If 'End If cnt += 1 row.Cells.Add(cell) 'End If Next 'для нужных ячеек в верхней строке, прописываем тексты объединяющих ячеек и их ColumnSpan For i = 1 To a.Count row.Cells(a(i)(1)).Text = a(i)(0) row.Cells(a(i)(1)).ColumnSpan = a(i)(2) - invisibleColsCount Next 'идем по верхней строке у оставшихся ячеек (не задействованных) в предыдущем цикле ставим им RowSpan = 2 'одновременно ячееки с таким же индексом в нижней строке помечаем на удаление For i = 0 To row.Cells.Count - 1 If row.Cells(i).Visible Then If row.Cells(i).ColumnSpan < 2 Then row.Cells(i).RowSpan = 2 r.Cells(i).ColumnSpan = 100 Else 'пропускаем ячейки на которые распространяется ColumnSpan i = i + row.Cells(i).ColumnSpan - 1 + invisibleColsCount End If End If Next 'удаляем помеченные ячейки в нижней строке i = 0 While i < r.Cells.Count If r.Cells(i).ColumnSpan = 100 Then r.Cells.RemoveAt(i) Else : i = i + 1 End If End While 'идем по верхней строке удаляем соответствующее ColumnSpan количество ячеек после ячеек имеющих ColumnSpan > 1 i = 0 While i < row.Cells.Count If row.Cells(i).ColumnSpan > 1 Then For j = 1 To row.Cells(i).ColumnSpan - 1 + invisibleColsCount row.Cells.RemoveAt(i + 1) Next End If i = i + 1 End While CType(gv.Controls(0), Table).Rows.AddAt(0, row) End If End Sub Public Sub CollectHeaderColumn(ByRef gv As GridView, colNumber As Integer, Optional referenceColNumber As Integer = -1) Dim curCell As New TableCell With {.Text = "."} Dim rowSpan As Integer = 1 Dim ColNumberToCheckText As Integer If referenceColNumber = -1 Then ColNumberToCheckText = colNumber Else ColNumberToCheckText = referenceColNumber End If Dim curText As String = "." For Each dr As GridViewRow In gv.Rows If dr.Cells(ColNumberToCheckText).Text <> curText Then 'curCell.Text Then If rowSpan > 1 Then curCell.RowSpan = rowSpan End If curCell = dr.Cells(colNumber) curText = dr.Cells(ColNumberToCheckText).Text rowSpan = 1 Else dr.Cells(colNumber).Visible = False rowSpan += 1 End If Next If rowSpan > 1 Then curCell.RowSpan = rowSpan End If End Sub Private Sub capa_Load(sender As Object, e As EventArgs) Handles Me.Load Dim sql As New StringBuilder sql.Clear() sql.AppendLine("--Принцип работы: выбираем все BN94 из производственного плана ") sql.AppendLine("--Делаем курсор, выбираем одну PCB в каждой итерации ") sql.AppendLine("--Для выбранной PCB выбираем все производственные ордера в указанном диапазоне дат. Ордера отсортированы по дате и времени производства asc ") sql.AppendLine("--К ордерам так же клеим уже отсканированный epass. Количество epass должно вычитаться из потребности, так как эти телеки уже собраны ") sql.AppendLine("--Делаем второй курсор (вложенный в первый) ") sql.AppendLine("--В каждой итерации из доступного стока для текущей PCB (WA) вычитаем потребность (количество в ордере) и прибавляем epass(столбец closed) ") sql.AppendLine("--Если на каком-то этапе доступный сток становится отрицательны, значит появляется short. Такой ордер записываем в таблицу @result ") sql.AppendLine("--Если расскоментировать break внутри второго лупа, то в результирующую таблицу попадёт только первый ордер с шортом по текущей PCB ") sql.AppendLine("--Если break закоментирован, то пададёт первый и все последующие ордера по текущец PCB, для которых есть short ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine("use [UserModules] ") sql.AppendLine("declare @PCB_cur as char(11) --Переменная для PCB сборки для текущей итерации курсора ") sql.AppendLine("declare @start_date as date --Диапазон производственных дат. Начало ") sql.AppendLine("declare @end_date as date --Диапазон производственных дат. Конец ") sql.AppendLine("--set @start_date = cast(getdte() as date) --Текущая дата для диапазона ") sql.AppendLine("--set @end_date = cast(getdate()+2 as date) -- +2 дня - конец диапазона ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine("set @start_date = (select top 1 REQMT_DATE from (select distinct top 3 REQMT_DATE from UserModules.[user].PICK_LIST_MAIN_LINE where REQMT_DATE >= cast(cast(getdate() as date) as varchar(10)) order by REQMT_DATE) t order by REQMT_DATE asc) ") sql.AppendLine("set @end_date = (select top 1 REQMT_DATE from (select distinct top 3 REQMT_DATE from UserModules.[user].PICK_LIST_MAIN_LINE where REQMT_DATE >= cast(cast(getdate() as date) as varchar(10)) order by REQMT_DATE) t order by REQMT_DATE desc) ") sql.AppendLine(" ") sql.AppendLine("declare @pcb_cursor_fetch_status as integer -- индикатор состояния очередной записи курсора (внешний луп). использовать @@FETCH_STATUS нельзя, так как в него попадает ПОСЛЕДНИЙ статус извлечения записи. Вложенный курсор будет затирать внешний ") sql.AppendLine("declare @p_p_cursor_fetch_status as integer -- индикатор состояния очередной записи курсора (вложенный луп). использовать @@FETCH_STATUS нельзя, так как в него попадает ПОСЛЕДНИЙ статус извлечения записи. Вложенный курсор будет затирать внешний ") sql.AppendLine(" ") sql.AppendLine("--Таблица для хранения производственного плана для каждой PCB. Заполняется после отработки процедуры ") sql.AppendLine("declare @prod_plan as table (po_no char(12), model_code varchar(max), plan_ymd char(8), plan_qty numeric, plan_start_dt varchar(14), material char(11), line_nm_new char(3), closed numeric ) ") sql.AppendLine("--Результирующая таблица с шортами ") sql.AppendLine("declare @result as table ([Production Order] char(12), [Model Code] varchar(max), [Production date] char(8), [Production qty] numeric, [Production start time] varchar(14), [PCB] char(11), [Line] char(3), [Short] numeric, [comment] varchar(max) ) ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine("--Переменные, в которые помещаются значения производственного плана текущей итерации во вложенном лупе из таблицы @prod_plan ") sql.AppendLine("declare @po_no char(12) ") sql.AppendLine("declare @model_code varchar(max) ") sql.AppendLine("declare @plan_ymd char(8) ") sql.AppendLine("declare @plan_qty numeric ") sql.AppendLine("declare @plan_start_dt varchar(14) ") sql.AppendLine("declare @material char(11) ") sql.AppendLine("declare @line_nm_new char(3) ") sql.AppendLine("declare @closed numeric ") sql.AppendLine("declare @current_stock numeric ") sql.AppendLine("declare @comment varchar(max) ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine("--Описание курсора для выбора всех PCB (BN94), которые понадобятся в производстве в диапазоне дат. ") sql.AppendLine("DECLARE PCB_CURSOR CURSOR FOR ") sql.AppendLine("( ") sql.AppendLine(" select ") sql.AppendLine(" distinct ") sql.AppendLine(" MATERIAL ") sql.AppendLine(" ") sql.AppendLine(" from UserModules.[user].PICK_LIST_MAIN_LINE TBOM ") sql.AppendLine(" ") sql.AppendLine(" where material like 'BN94%' ") sql.AppendLine(" and REQMT_DATE between @start_date and @end_date ") sql.AppendLine(" --ЗАГЛУШКА ") sql.AppendLine(" --and material = 'BN94-11488A' ") sql.AppendLine(" --КОНЕЦ ЗАГЛУШКИ ") sql.AppendLine(") ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine("delete from @prod_plan --Зачищаем таблицу. Значения формируются каждый раз заново для каждой PCB ") sql.AppendLine("insert into @prod_plan exec check_short @start = @start_date, @end = @end_date --Заполняем таблицу ") sql.AppendLine(" ") sql.AppendLine("--Внешний луп по всем PCB ") sql.AppendLine("OPEN PCB_CURSOR ") sql.AppendLine(" FETCH NEXT FROM PCB_CURSOR INTO @PCB_cur ") sql.AppendLine(" set @pcb_cursor_fetch_status = @@FETCH_STATUS ") sql.AppendLine(" WHILE @pcb_cursor_fetch_status = 0 ") sql.AppendLine(" BEGIN ") sql.AppendLine(" ") sql.AppendLine(" --Определяем курсор для производственных ордеров, в которых используется текущая PCB ") sql.AppendLine(" declare p_p_cursor cursor for ") sql.AppendLine(" ( ") sql.AppendLine(" select ") sql.AppendLine(" PO_NO ") sql.AppendLine(" ,MODEL_CODE ") sql.AppendLine(" ,PLAN_YMD ") sql.AppendLine(" ,PLAN_QTY ") sql.AppendLine(" ,PLAN_START_DT ") sql.AppendLine(" ,MATERIAL ") sql.AppendLine(" ,LINE_NM_NEW ") sql.AppendLine(" ,closed ") sql.AppendLine(" ,comment ") sql.AppendLine(" from @prod_plan pl ") sql.AppendLine(" left join UserModules.[user].[SMD_PCB_SHORT_COMMENTS] com ") sql.AppendLine(" on pl.PO_NO = com.po ") sql.AppendLine(" where material = @PCB_cur ") sql.AppendLine(" ) ") sql.AppendLine(" ") sql.AppendLine(" --Вложенный луп для подсчёта шортов ") sql.AppendLine(" OPEN p_p_cursor ") sql.AppendLine(" FETCH NEXT FROM p_p_cursor INTO @po_no,@model_code, @plan_ymd, @plan_qty, @plan_start_dt, @material, @line_nm_new, @closed, @comment ") sql.AppendLine(" set @p_p_cursor_fetch_status = @@FETCH_STATUS ") sql.AppendLine(" ") sql.AppendLine(" --Получаем сток для текущей PCB. Таблица формируется скриптом WA ") sql.AppendLine(" set @current_stock = (select ") sql.AppendLine(" isnull(sum(cast(qty as numeric)), 0) as qty ") sql.AppendLine(" from [UserModules].[user].[SMD_STOCK_PCB_SHORT] ") sql.AppendLine(" where material = @pcb_cur) ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine(" WHILE @p_p_cursor_fetch_status = 0 ") sql.AppendLine(" BEGIN ") sql.AppendLine(" --Вычитаем из доступного стока потребности с учётом уже отсканированных epass ") sql.AppendLine(" set @current_stock = @current_stock - @plan_qty + @closed ") sql.AppendLine(" if @current_stock < 0 ") sql.AppendLine(" begin ") sql.AppendLine(" insert into @result values (@po_no, @model_code, @plan_ymd, @plan_qty, @plan_start_dt, @material, @line_nm_new, @current_stock, @comment) ") sql.AppendLine(" --break; --Если раскоментить, то в результат попадёт только первый ордер с шортом. Остальные будут проигнорированны ") sql.AppendLine(" end ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine(" FETCH NEXT FROM p_p_cursor INTO @po_no,@model_code, @plan_ymd, @plan_qty, @plan_start_dt, @material, @line_nm_new, @closed, @comment ") sql.AppendLine(" set @p_p_cursor_fetch_status = @@FETCH_STATUS ") sql.AppendLine(" ") sql.AppendLine(" END ") sql.AppendLine(" CLOSE p_p_cursor ") sql.AppendLine(" DEALLOCATE p_p_cursor ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine(" FETCH NEXT FROM PCB_CURSOR INTO @PCB_cur ") sql.AppendLine(" set @pcb_cursor_fetch_status = @@FETCH_STATUS ") sql.AppendLine(" END ") sql.AppendLine(" ") sql.AppendLine(" ") sql.AppendLine(" CLOSE PCB_CURSOR ") sql.AppendLine(" DEALLOCATE PCB_CURSOR ") sql.AppendLine(" ") sql.AppendLine(" --Выводим результат ") sql.AppendLine(" select ") sql.AppendLine(" [Production Order] ") sql.AppendLine(" ,Line ") sql.AppendLine(" ,[Model Code] ") sql.AppendLine(" ,substring([Production date],1,4) + '-' + substring([Production date],5,2) + '-' + substring([Production date],7,2) as [Production date] ") sql.AppendLine(" ,[Production qty] ") sql.AppendLine(" ,substring([Production start time],1,4) + '-' + SUBSTRING([Production start time],5,2) + '-' + substring([Production start time], 7,2) + ' ' + substring([Production start time], 9,2) + ':' + substring([Production start time], 11,2) + ':' + substring([Production start time], 13,2) as [Production start time] ") sql.AppendLine(" ,PCB ") sql.AppendLine(" ,Short ") sql.AppendLine(" ,comment as Reason") sql.AppendLine(" from @result ") sql.AppendLine(" order by [Production start time] ") queue.SelectCommand = sql.ToString report.DataSource = queue Try report.DataBind() Catch ex As Exception Dim debug As Integer = 16 End Try prepare_data() End Sub Sub prepare_data() Try Dim dr As Data.DataRow = sqlf.GetRow("select distinct top 1 stock_date as stock_date from [UserModules].[user].[SMD_STOCK_PCB_SHORT]") If Not IsNothing(dr) Then 'Title = dr("MODULE_NAME") Dim stock_date As String = dr("stock_date") stock_date_time.Text = "PCB stock last updated on: " date_time.Text = stock_date HiddenField.Value = stock_date date_time.Visible = True End If Dim bt_stat As Data.DataRow = sqlf.GetRow("select * from UserModules.[user].WA_JOB_LIST WHERE id=68 ") If Not IsNothing(bt_stat) Then If bt_stat("RUN_IMMEDIATELY") = "Y" Or bt_stat("NOW_RUNNING") = "Y" Then 'Stock.Text = "The stock data is being extracted " spinner.Visible = True Stock.Enabled = False stock_date_time.Text = "Stock data is being extracted at the moment. The page will be reloaded automatically when it's done" date_time.Visible = False End If End If Catch ex As Exception Dim debug As Integer = 16 End Try End Sub Private Sub report_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles report.RowDataBound Dim i As Integer = 0 Dim po As String If e.Row.RowType <> DataControlRowType.Header Then For Each cell As TableCell In e.Row.Cells If i = 0 Then po = cell.Text End If If i = 8 Then cell.Attributes.Add("class", "remark") cell.Attributes.Add("id", po) End If i = i + 1 Next End If End Sub Private Sub report_RowCommand(sender As Object, e As GridViewCommandEventArgs) Handles report.RowCommand End Sub Private Sub SqlDataSource_Selecting(sender As Object, e As SqlDataSourceSelectingEventArgs) Handles queue.Selecting e.Command.CommandTimeout = 3600 End Sub Private Sub report_Init(sender As Object, e As EventArgs) Handles report.Init End Sub Private Sub report_PreRender(sender As Object, e As EventArgs) Handles report.PreRender 'report.Columns(7).Visible = False 'report.Columns(6).Visible = False End Sub Protected Sub stock_Click(sender As Object, e As EventArgs) Handles Stock.Click Dim sqlf As New sharedClasses.dbFunctions.SqlFunctions sqlf.NonQuery("Update UserModules.[user].WA_JOB_LIST Set RUN_IMMEDIATELY='Y' WHERE id=68 ") prepare_data() End Sub End Class