در این مقاله میخواهیم با هم روش ایجاد یک زمانبندی اجرای پروژه ی ساده از دیتابیس با استفاده از Stored Procedure با Pivot result را بیاموزیم.
همچنین در ادامه نمایش نتیجه در MVC با استفاده از AngularJS و WebAPI 2 بدون استفاده از Entity Framework را خواهیم دید.
برای درک بهتر نیز در ادامه ی مطلب سورس پروژه را برای دانلود قرار داده ایم. با ما همراه باشید …
در این مثال من از Entity Framework استفاده نکرده ام.
دلیل عدم استفاده از EF این است که برای استفاده از EF نیاز داریم که نتیجه را همراه با ستون هایی ثابت (ستون ها باید مشخص باشند) دریافت کنیم.
به عنوان مثال از قسمت Stored Procedure ما عموما نتیجه ی انتخابی مانند (“select column1,column2,column3 from table”) را خواهیم داشت.
اما در این مثال من از Pivot result استفاده میکنم و ستون ها به صورت داینامیکی بر اساس طول تاریخ نمایش داده میشوند و من از “exec sp_executesql @SQLquery” در SP خودم برای اجرای query های داینامیک استفاده میکنم.
به جای استفاده از Entity Framework در Web API من مستقیما به دیتابیس متصل میشوم و SP را اجرا میکنم تا نتیجه را بدست بیاورم.
از طریق کنترل AngularJS ام نیز متد Web API را فراخوانی میکنیم تا نتیجه بازگردانده شود.
زمانبندی اجرا پروژه
زمانبندی پروژه یکی از مهمترین بخش های برنامه ریزی یک پروژه است.
پروژه ممکن است از هر نوعی باشد ، به عنوان مثال برنامه ریزی برنامه نویسان پروژه های نرم افزاری ، برنامه ریزی محصولات و غیره.
برای یک مثال واقعی بیاید یک کمپانی تولید صندلی ماشین را در نظر بگیریم.
هر هفته آنها به عنوان مثال ۱۰۰ صندلی برای یک مدل ماشین تولید میکنند.
در این کارخانه همه چیزی بر اساس برنامه ریزی پیش میرود. مثلا از این هفته از دوشنبه ی این هفته تا جمعه ۱۰۰ عدد صندلی باید ساخته و ارسال شود.
اما بنا به دلایلی کارخانه تنها قادر به ساخت ۹۰ عدد صندلی بوده اند. برای ردگیری برنامه ی تولید با برنامه ی واقعی از یک نمودار زمانبندی محصولات استفاده میکنیم.
برنامه ی تولید شامل تاریخ شروع و تاریخ اتمام است ؛ زمانی که کار تولید محصول شروع میشود و زمانی که ساخت محصولات باید به اتمام برسد.
تاریخ واقعی ، تاریخ اصلی شروع و پایان تاریخ تولید محصولات است. تاریخ واقعی پس از اتمام تولید محصولات تعیین میشود.
اگر تاریخ واقعی برابر یا کمتر از تاریخ پایان بود ، واضح است که کار سر وقت یا زودتر از موعود انجام شده است و آماده ی ارسال به مشتری است.
اگر زمان واقعی از تاریخ پایانی گذشته باشد ، آنگاه خط تولید باید به دقت تحت نظارت باشد تا بار دیگر این تاخیر رفع شود.
در پروژه ممکن است ۲ تاریخ موجود باشد ، یکی تاریخ های شروع و پایان (این ها تاریخ هایی هستند که برای انجام کار درنظر گرفته شده اند.) و دیگری تاریخ واقعی شروع و پایان کار است (این ها تاریخ هایی هستند که کار واقعا شروع و پایان یافته اند.)
برای همه ی پروژه ها نیاز داریم که تاریخ های واقعی و زمانبندی شده را مقایسه کنیم.
بخش کد
۱- ایجاد دیتابیس و جدول
یک جدول با نام SCHED_Master تحت دیتابیس projectDB ایجاد میکنیم.
در زیر script برای ایجاد یک دیتابیس ، جدول و نمونه ی query های وارد شده آورده شده است.
این script را در SQL Server خود اجرا کنید. من از SQL Server 2012 استفاده کرده ام.
--Script to create DB,Table and sample Insert data USE MASTER GO -- ۱) Check for the Database Exists .If the database is exist then drop and create new DB IF EXISTS (SELECT [name] FROM sys.databases WHERE [name] = 'projectDB' ) DROP DATABASE projectDB GO CREATE DATABASE projectDB GO USE projectDB GO CREATE TABLE [dbo].[SCHED_Master]( [ID] [int] NOT NULL, [ProjectName] [varchar](100) NULL, [ProjectType] int NULL, [ProjectTypeName] [varchar](100) NULL, [SCHED_ST_DT] [datetime] NULL, [SCHED_ED_DT] [datetime] NULL, [ACT_ST_DT] [datetime] NULL, [ACT_ED_DT] [datetime] NULL, [status] int null PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] -- Insert Query INSERT INTO [dbo].SCHED_Master ([ID],[ProjectName],[ProjectType],[ProjectTypeName],[SCHED_ST_DT],[SCHED_ED_DT],[ACT_ST_DT],[ACT_ED_DT],[status]) VALUES (۱۰۰۱,'Project1',1,'Urgent','2015-06-01 00:00:00.000','2015-09-02 00:00:00.000' ,'۲۰۱۵-۰۶-۲۲ ۰۰:۰۰:۰۰.۰۰۰','۲۰۱۵-۰۸-۲۶ ۰۰:۰۰:۰۰.۰۰۰',۱) INSERT INTO [dbo].SCHED_Master ([ID],[ProjectName],[ProjectType],[ProjectTypeName],[SCHED_ST_DT],[SCHED_ED_DT],[ACT_ST_DT],[ACT_ED_DT],[status]) VALUES (۱۰۰۲,'Project1',2,'Important','2015-09-22 00:00:00.000','2015-12-22 00:00:00.000' ,'۲۰۱۵-۰۹-۱۹ ۰۰:۰۰:۰۰.۰۰۰','۲۰۱۵-۱۲-۲۹ ۰۰:۰۰:۰۰.۰۰۰',۱) INSERT INTO [dbo].SCHED_Master ([ID],[ProjectName],[ProjectType],[ProjectTypeName],[SCHED_ST_DT],[SCHED_ED_DT],[ACT_ST_DT],[ACT_ED_DT],[status]) VALUES (۱۰۰۳,'Project1',3,'Normal','2016-01-01 00:00:00.000','2016-03-24 00:00:00.000' ,'۲۰۱۶-۰۱-۰۱ ۰۰:۰۰:۰۰.۰۰۰','۲۰۱۶-۰۳-۱۴ ۰۰:۰۰:۰۰.۰۰۰',۱) INSERT INTO [dbo].SCHED_Master ([ID],[ProjectName],[ProjectType],[ProjectTypeName],[SCHED_ST_DT],[SCHED_ED_DT],[ACT_ST_DT],[ACT_ED_DT],[status]) VALUES (۱۰۰۴,'Project2',1,'Urgent','2015-07-01 00:00:00.000','2015-09-02 00:00:00.000' ,'۲۰۱۵-۰۷-۲۲ ۰۰:۰۰:۰۰.۰۰۰','۲۰۱۵-۰۸-۲۶ ۰۰:۰۰:۰۰.۰۰۰',۱) INSERT INTO [dbo].SCHED_Master ([ID],[ProjectName],[ProjectType],[ProjectTypeName],[SCHED_ST_DT],[SCHED_ED_DT],[ACT_ST_DT],[ACT_ED_DT],[status]) VALUES (۱۰۰۵,'Project2',2,'Important','2015-09-29 00:00:00.000','2015-12-22 00:00:00.000' ,'۲۰۱۵-۰۹-۰۸ ۰۰:۰۰:۰۰.۰۰۰','۲۰۱۵-۱۲-۱۴ ۰۰:۰۰:۰۰.۰۰۰',۱) INSERT INTO [dbo].SCHED_Master ([ID],[ProjectName],[ProjectType],[ProjectTypeName],[SCHED_ST_DT],[SCHED_ED_DT],[ACT_ST_DT],[ACT_ED_DT],[status]) VALUES (۱۰۰۶,'Project2',3,'Normal','2016-01-01 00:00:00.000','2016-03-04 00:00:00.000' ,'۲۰۱۶-۰۱-۰۱ ۰۰:۰۰:۰۰.۰۰۰','۲۰۱۶-۰۲-۲۴ ۰۰:۰۰:۰۰.۰۰۰',۱) -- Select Query select ID,ProjectName,ProjectType,ProjectTypeName,SCHED_ST_DT,SCHED_ED_DT,ACT_ST_DT,ACT_ED_DT,status from SCHED_Master
Query ها را وارد کنید
INSERT INTO[dbo].SCHED_Master([ID], [ProjectName], [ProjectType], [ProjectTypeName], [SCHED_ST_DT], [SCHED_ED_DT], [ACT_ST_DT], [ACT_ED_DT], [status]) VALUES(1001, 'Project1', 1, 'Urgent', '2015-06-01 00:00:00.000', '2015-09-02 00:00:00.000', '2015-06-22 00:00:00.000', '2015-08-26 00:00:00.000', 1) INSERT INTO[dbo].SCHED_Master([ID], [ProjectName], [ProjectType], [ProjectTypeName], [SCHED_ST_DT], [SCHED_ED_DT], [ACT_ST_DT], [ACT_ED_DT], [status]) VALUES(1002, 'Project1', 2, 'Important', '2015-09-22 00:00:00.000', '2015-12-22 00:00:00.000', '2015-09-19 00:00:00.000', '2015-12-29 00:00:00.000', 1) INSERT INTO[dbo].SCHED_Master([ID], [ProjectName], [ProjectType], [ProjectTypeName], [SCHED_ST_DT], [SCHED_ED_DT], [ACT_ST_DT], [ACT_ED_DT], [status]) VALUES(1003, 'Project1', 3, 'Normal', '2016-01-01 00:00:00.000', '2016-03-24 00:00:00.000', '2016-01-01 00:00:00.000', '2016-03-14 00:00:00.000', 1) INSERT INTO[dbo].SCHED_Master([ID], [ProjectName], [ProjectType], [ProjectTypeName], [SCHED_ST_DT], [SCHED_ED_DT], [ACT_ST_DT], [ACT_ED_DT], [status]) VALUES(1004, 'Project2', 1, 'Urgent', '2015-07-01 00:00:00.000', '2015-09-02 00:00:00.000', '2015-07-22 00:00:00.000', '2015-08-26 00:00:00.000', 1) INSERT INTO[dbo].SCHED_Master([ID], [ProjectName], [ProjectType], [ProjectTypeName], [SCHED_ST_DT], [SCHED_ED_DT], [ACT_ST_DT], [ACT_ED_DT], [status]) VALUES(1005, 'Project2', 2, 'Important', '2015-09-29 00:00:00.000', '2015-12-22 00:00:00.000', '2015-09-08 00:00:00.000', '2015-12-14 00:00:00.000', 1) INSERT INTO[dbo].SCHED_Master([ID], [ProjectName], [ProjectType], [ProjectTypeName], [SCHED_ST_DT], [SCHED_ED_DT], [ACT_ST_DT], [ACT_ED_DT], [status]) VALUES(1006, 'Project2', 3, 'Normal', '2016-01-01 00:00:00.000', '2016-03-04 00:00:00.000', '2016-01-01 00:00:00.000', '2016-02-24 00:00:00.000', 1)
Select Query
select ID,ProjectName,ProjectType,ProjectTypeName,SCHED_ST_DT,SCHED_ED_DT,ACT_ST_DT,ACT_ED_DT,status from SCHED_Master;
پس از ایجاد جدول ، یک Stored Procedure برای نمایش نتیجه ی زمانبندی پروژه با استفاده از Pivot query میسازیم.
من هر گام از روشم را توضیح میدهم تا درک آن برایتان واضح باشد و بتوانید برای خودتان با فرمت جدول خودتان هم ایجاد کنید.
گام اول
Procedure ای با یک پارامتر ایجاد کنید و متغیر ها را در داخل Procedure برای استفاده در SP مشخص کنید.
به یاد داشته باشید که من Formdate و Todate را Static در نظر گرفته ام.
میتوانید آن را به عنوان یک پارامتر از SP برای دریافت نتیجه های داینامیکی بر اساس طول تاریخ تغییر دهید.
گام دوم
ما تاریخ شروع و پایان پروژه را مشخص کرده ایم. حال باید نتیجه ی زمانبندی پروژه را با تاریخ های داده شده پیدا کنیم.
هدف اصلی از نمودار زمانبندی پروژه این است که طول تاریخ را به عنوان هفته ها ، ماه ها ، سال ها یا روز ها یا هر فرمتی از این قبیل به عنوان نتیجه ی دنباله دار داشته باشیم.
برای دریافت نتایج دنباله دار تعداد روز های یکشنبه را از تاریخ شروع تا تاریخ پایان را دریافت میکنیم.
نتیجه را به عنوان نمایش هفته ، نشان میدهم. پس در اینجا من از هر هفته برای تاریخ یکشنبه استفاده میکنم و همه تاریخ ها را در یک جدول برای نمایش نتایج ، ذخیره میکنم.
-- ۲.This Temp table is to created for get all the days between the start date and end date to display as the Column Header --۲.Start ///////////// IF OBJECT_ID('tempdb..#TEMP_EveryWk_Sndays') IS NOT NULL DROP TABLE #TEMP_EveryWk_Sndays DECLARE @TOTALCount INT Select @TOTALCount= DATEDIFF(dd,@FromDate,@ToDate); WITH d AS ( SELECT top (@TOTALCount) AllDays = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY object_id), REPLACE(@FromDate,'-','')) FROM sys.all_objects ) SELECT distinct DATEADD(DAY, 1 - DATEPART(WEEKDAY, AllDays), CAST(AllDays AS DATE))WkStartSundays ,1 as status into #TEMP_EveryWk_Sndays FROM d where AllDays = @ToDate AND AllDays = @FromDate -- test the sample temptable with select query -- select * from #TEMP_EveryWk_Sndays --///////////// End of 2.
گام سوم
من جدول temp بالا را با جدول زمانبندی واقعی متحد میکنم تا بتوانیم تاریخ ها را مقایشه کنیم و نتیجه را تولید کنیم.
ابتدا نتیجه ی زمانبندی را چک میکنم و با استفاده از Union نتیجه را با نتیجه ی واقعی ترکیب میکنم و نتیجه ی نهایی را در جدول temp دیگری برای تولید pivot result وارد میکنیم.
زمانبندی اجرا پروژه
یادداشت
برای تاریخ های واقعی در لیست Pivot نتایج را همانند زیر نشان خواهم داد :
“-۱” : برای تاریخ پایان هر دو نتیجه ی واقعی و زمانبندی شده. در برنامه ،من مقادیر تولید شده را چک میکنم ؛ اگر -۱ بود ، آنگاه متن “END” را با پس زمینه ای قرمز برای اخطار به کاربر به منظور تاریخ اتمام هر پروژه ، نمایش خواهم داد.
“۰” : اگر نتیجه ۰ بود ، به این معناست که روز ها در هیچ یک از روز های واقعی و زمانبندی شده وجود ندارد ، پس باید خالی باقی بماند.
“۱” : اگر نتیجه ۱ بود ، نشان دهنده ی تاریخ شروع و پایان روز های زمانبندی شده است.
من از رنگ آبی برای نمایش روز های زمانبندی شده استفاده میکنم.
“۲” : اگر نتیجه ۲ بود ، نشان دهنده ی تاریخ شروع و پایان روز های واقعی است.
من از رنگ سبز برای نمایش روز های واقعی استفاده میکنم.
این تنها یک نمونه Procedure است که یک نمونه برنامه برای زمانبندی پروژه ارائه میدهد.
میتوانید این جدول را بر اساسProcedure و برنامه بسته به نیاز های خودتان ، به سلیقه خودتان دربیاورید. میتوانید قوانین و وضعیت
های خودتان را برای نمایش نتیجه پیاده کنید.
-- ۳. This temp table is created toScedule details with result here i have used the Union , --the 1st query return the Schedule Project result and the 2nd query returns the Actual Project result both this query will be inserted to a Temp Table --۳.Start ///////////// IF OBJECT_ID('tempdb..#TEMP_results') IS NOT NULL DROP TABLE #TEMP_results SELECT ProjectName,viewtype,ProjectType,resultnew,YMWK INTO #TEMP_results FROM( SELECT A.ProjectName ProjectName -- Our Project Name ,'۱-Scd' viewtype -- Our View type first we display Schedule Data and then Actual , A. ProjectType ProjectType -- Our Project type here you can use your own status as Urgent,normal and etc , Case when cast(DATEPART( wk, max(A.SCHED_ED_DT)) as varchar(2)) = cast(DATEPART( wk, WkStartSundays) as varchar(2)) then -1 else case when min(A.SCHED_ST_DT)= F.WkStartSundays AND max(A.SCHED_ED_DT) = F.WkStartSundays then 1 else 0 end end resultnew -- perfectResult as i expect , RIGHT(YEAR(WkStartSundays), 2)+'-'+'W'+convert(varchar(2),Case when len(DATEPART( wk, WkStartSundays))='1' then '0'+ cast(DATEPART( wk, WkStartSundays) as varchar(2)) else cast(DATEPART( wk, WkStartSundays) as varchar(2)) END ) as 'YMWK' -- Here we display Year/month and Week of our Schedule which will be displayed as the Column FROM -- here you can youe your own table SCHED_Master A (NOLOCK) LEFT OUTER JOIN #TEMP_EveryWk_Sndays F (NOLOCK) ON A.status= F.status WHERE -- Here you can check your own where conditions A.ProjectName like '%' + @projectId AND A.status=1 AND A.ProjectType in (1,2,3) AND A.SCHED_ST_DT = @ToDate AND A.SCHED_ED_DT = @FromDate GROUP BY A.ProjectName , A. ProjectType ,A.SCHED_ED_DT ,F.WkStartSundays UNION -- This query is to result the Actual result SELECT A.ProjectName ProjectName -- Our Project Name ,'۲-Act' viewtype -- Our View type first we display Schedule Data and then Actual , A. ProjectType ProjectType -- Our Project type here you can use your own status as Urgent,normal and etc , Case when cast(DATEPART( wk, max(A.ACT_ED_DT)) as varchar(2)) = cast(DATEPART( wk, WkStartSundays) as varchar(2)) then -1 else case when min(A.ACT_ST_DT)= F.WkStartSundays AND max(A.ACT_ED_DT) = F.WkStartSundays then 2 else 0 end end resultnew -- perfectResult as i expect , RIGHT(YEAR(WkStartSundays), 2)+'-'+'W'+convert(varchar(2),Case when len(DATEPART( wk, WkStartSundays))='1' then '0'+ cast(DATEPART( wk, WkStartSundays) as varchar(2)) else cast(DATEPART( wk, WkStartSundays) as varchar(2)) END ) as 'YMWK' -- Here we display Year/month and Week of our Schedule which will be displayed as the Column FROM -- here you can youe your own table SCHED_Master A (NOLOCK) LEFT OUTER JOIN #TEMP_EveryWk_Sndays F (NOLOCK) ON A.status= F.status WHERE -- Here you can check your own where conditions A.ProjectName like '%' + @projectId AND A.status=1 AND A.ProjectType in (1,2,3) AND A.ACT_ST_DT = @ToDate AND A.ACT_ED_DT = @FromDate GROUP BY A.ProjectName , A. ProjectType ,A.SCHED_ED_DT ,F.WkStartSundays ) q --۳.End /////////////
گام چهارم
در اینجا نتیجه ی نهایی را با استفاده از Pivot query از نتیجه ی نهایی از نتایج جدول temp نمایش میدهیم.
--۴.Start ///////////// --here first we get all the YMWK which should be display in Columns we use this in our next pivot query select @MyColumns = STUFF((SELECT ',' + QUOTENAME(YMWK) FROM #TEMP_results GROUP BY YMWK ORDER BY YMWK FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,۱,۱,'') --here we use the above all YMWK to disoplay its result as column and row display set @SQLquery = N'SELECT ProjectName,viewtype,ProjectType,' + @MyColumns + N' from ( SELECT ProjectName, viewtype, ProjectType, YMWK, resultnew as resultnew FROM #TEMP_results ) x pivot ( sum(resultnew) for YMWK in (' + @MyColumns + N') ) p order by ProjectName, ProjectType,viewtype' exec sp_executesql @SQLquery; </pre> در زیر نیز کد کامل مربوط به Stored Procedure آورده شده است: <pre class="lang:mysql decode:true ">Alter PROCEDURE [dbo].[usp_ProjectSchedule_Select] @projectId VARCHAR(10) = '' AS BEGIN -- ۱. Declared for setting the Schedule Start and End date --۱.Start ///////////// Declare @FromDate VARCHAR(20) = '2015-06-08'--DATEADD(mm,-12,getdate()) Declare @ToDate VARCHAR(20) = '2016-05-06'--DATEADD(mm, 1, getdate()) -- used for the pivot table result DECLARE @MyColumns AS NVARCHAR(MAX), @SQLquery AS NVARCHAR(MAX) --// End of 1. -- ۲.This Temp table is to created for get all the days between the start date and end date to display as the Column Header --۲.Start ///////////// IF OBJECT_ID('tempdb..#TEMP_EveryWk_Sndays') IS NOT NULL DROP TABLE #TEMP_EveryWk_Sndays DECLARE @TOTALCount INT Select @TOTALCount= DATEDIFF(dd,@FromDate,@ToDate); WITH d AS ( SELECT top (@TOTALCount) AllDays = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY object_id), REPLACE(@FromDate,'-','')) FROM sys.all_objects ) SELECT distinct DATEADD(DAY, 1 - DATEPART(WEEKDAY, AllDays), CAST(AllDays AS DATE))WkStartSundays ,1 as status into #TEMP_EveryWk_Sndays FROM d where AllDays = @ToDate AND AllDays = @FromDate -- test the sample temptable with select query -- select * from #TEMP_EveryWk_Sndays --///////////// End of 2. -- ۳. This temp table is created toScedule details with result here i have used the Union , --the 1st query return the Schedule Project result and the 2nd query returns the Actual Project result both this query will be inserted to a Temp Table --۳.Start ///////////// IF OBJECT_ID('tempdb..#TEMP_results') IS NOT NULL DROP TABLE #TEMP_results SELECT ProjectName,viewtype,ProjectType,resultnew,YMWK INTO #TEMP_results FROM( SELECT A.ProjectName ProjectName -- Our Project Name ,'۱-Scd' viewtype -- Our View type first we display Schedule Data and then Actual , A. ProjectType ProjectType -- Our Project type here you can use your own status as Urgent,normal and etc , Case when cast(DATEPART( wk, max(A.SCHED_ED_DT)) as varchar(2)) = cast(DATEPART( wk, WkStartSundays) as varchar(2)) then -1 else case when min(A.SCHED_ST_DT)= F.WkStartSundays AND max(A.SCHED_ED_DT) = F.WkStartSundays then 1 else 0 end end resultnew -- perfectResult as i expect , RIGHT(YEAR(WkStartSundays), 2)+'-'+'W'+convert(varchar(2),Case when len(DATEPART( wk, WkStartSundays))='1' then '0'+ cast(DATEPART( wk, WkStartSundays) as varchar(2)) else cast(DATEPART( wk, WkStartSundays) as varchar(2)) END ) as 'YMWK' -- Here we display Year/month and Week of our Schedule which will be displayed as the Column FROM -- here you can youe your own table SCHED_Master A (NOLOCK) LEFT OUTER JOIN #TEMP_EveryWk_Sndays F (NOLOCK) ON A.status= F.status WHERE -- Here you can check your own where conditions A.ProjectName like '%' + @projectId AND A.status=1 AND A.ProjectType in (1,2,3) AND A.SCHED_ST_DT = @ToDate AND A.SCHED_ED_DT = @FromDate GROUP BY A.ProjectName , A. ProjectType ,A.SCHED_ED_DT ,F.WkStartSundays UNION -- This query is to result the Actual result SELECT A.ProjectName ProjectName -- Our Project Name ,'۲-Act' viewtype -- Our View type first we display Schedule Data and then Actual , A. ProjectType ProjectType -- Our Project type here you can use your own status as Urgent,normal and etc , Case when cast(DATEPART( wk, max(A.ACT_ED_DT)) as varchar(2)) = cast(DATEPART( wk, WkStartSundays) as varchar(2)) then -1 else case when min(A.ACT_ST_DT)= F.WkStartSundays AND max(A.ACT_ED_DT) = F.WkStartSundays then 2 else 0 end end resultnew -- perfectResult as i expect , RIGHT(YEAR(WkStartSundays), 2)+'-'+'W'+convert(varchar(2),Case when len(DATEPART( wk, WkStartSundays))='1' then '0'+ cast(DATEPART( wk, WkStartSundays) as varchar(2)) else cast(DATEPART( wk, WkStartSundays) as varchar(2)) END ) as 'YMWK' -- Here we display Year/month and Week of our Schedule which will be displayed as the Column FROM -- here you can youe your own table SCHED_Master A (NOLOCK) LEFT OUTER JOIN #TEMP_EveryWk_Sndays F (NOLOCK) ON A.status= F.status WHERE -- Here you can check your own where conditions A.ProjectName like '%' + @projectId AND A.status=1 AND A.ProjectType in (1,2,3) AND A.ACT_ST_DT = @ToDate AND A.ACT_ED_DT = @FromDate GROUP BY A.ProjectName , A. ProjectType ,A.SCHED_ED_DT ,F.WkStartSundays ) q --۳.End ///////////// --۴.Start ///////////// --here first we get all the YMWK which should be display in Columns we use this in our next pivot query select @MyColumns = STUFF((SELECT ',' + QUOTENAME(YMWK) FROM #TEMP_results GROUP BY YMWK ORDER BY YMWK FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,۱,۱,'') --here we use the above all YMWK to disoplay its result as column and row display set @SQLquery = N'SELECT ProjectName,viewtype,ProjectType,' + @MyColumns + N' from ( SELECT ProjectName, viewtype, ProjectType, YMWK, resultnew as resultnew FROM #TEMP_results ) x pivot ( sum(resultnew) for YMWK in (' + @MyColumns + N') ) p order by ProjectName, ProjectType,viewtype' exec sp_executesql @SQLquery; END
ایجاد برنامه وب MVC در ویژوال استودیوی ۲۰۱۵
پس از نصب ویژوال استودیوی ۲۰۱۵ بر روی Programes<- start کلیک کنید و سپس ویژوال استودیو را انتخاب کنید و بر روی Visual Studio 2015 RC کلیک کنید.
به مسیر زیر بروید :
- New -Project -Select Web -ASP.NET Web Application
مکانی برای ذخیره ی پروژه تان انتخاب کنید و نامی برای پروژه انتخاب کنید.
زمانبندی اجرا پروژه
MVC را انتخاب کنید و در قسمت Add Folders and Core Refrences گزینه ی Web API را انتخاب کنید و بر روی OK کلیک کنید.
روش افزودن کنترلر Web API
بر روی فولدر کنترلر راست کلیک کنید و سپس بر روی Add و Controller کلیک کنید.
از آنجایی که خودمان کنترلر Web API مان را میسازیم ، کنترلر را انتخاب کنید و یک Empty Web API 2 Controller اضافه کنید.
نامی مناسب برای این کنترلر Web API انتخاب کنید و OK را کلیک کنید. در اینجا من از نام “ScheduleController” استفاده کرده ام.
زمانبندی اجرا پروژه
از آنجایی که خودمان Web API را ایجاد کرده ایم ، میتوانیم ببینیم که کنترلرمان از ApiController ارث بری کرده است.
همچنین همگی میدانیم که Web API یک HTTP Service آسان و راحت ساخت برای جستجوگر ها و موبایل ها است.
- Web API شامل ۴ متد Get/Post/Put/Delete است.
- Get : برای در خواست داده است (select).
- Post : برای ایجاد داده است (insert).
- Put : برای به روز رسانی داده ها است.
- Delete : برای حذف داده ها است.
در این مثال از متد Get استفاده میکنیم زیرا نیازی داریم که زمانبندی های پروژه ها را از جایی بگیریم.
متد GET
در مثال این مقاله من تنها از متد Get استفاده کرده ام زیرا من تنها از یک Stored Procedure استفده میکنم.
از آنجایی که من از Entity Framework استفاده نکرده ام ، در این جا من به دیتابیس متصل شده ام و نتایجStored Procedure را از دیتابیس گرفته ام.
public class scheduleController: ApiController { // to Search Student Details and display the result [HttpGet] public DataTable projectScheduleSelect(string projectID) { string connStr = ConfigurationManager.ConnectionStrings["shanuConnectionString"].ConnectionString; DataTable dt = new DataTable(); SqlConnection objSqlConn = new SqlConnection(connStr); objSqlConn.Open(); SqlCommand command = new SqlCommand("usp_ProjectSchedule_Select", objSqlConn); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add("@projectId", SqlDbType.VarChar).Value = projectID; SqlDataAdapter da = new SqlDataAdapter(command); da.Fill(dt); return dt; } }
در WebConfig منConnection string دیتابیس را تنظیم کرده ام. در متد Get مربوط به Web API من Connection string را خوانده ام و DB Connection را راه اندازی کرده ام. با استفاده از SQL Adapter نتایج را از Stored Procedure با پاس دادن آرگومان دریافت میکنیم و نتایج نهایی را در DataTable قرار میدهیم و DataTable را برمیگردانیم.
ایجاد کنترلر AngularJS
ابتدا یک فولدر جدید در داخل فولدر Script ایجاد کنیدو نام MyAngular را برای آن در نظر بگیرید.
زمانبندی اجرا پروژه
حال کنترلر Angular را در داخل این فولدر اضافه کنید.
بر روی فولدر MyAngular راست کلیک کنید و گزینه ی افزودنه را انتخاب کنید و Add New Item را انتخاب کنید .
سپس گزینه ی Web و پس از آن گزینه ی AngularJS Controller را انتخاب کنید و نامی مناسب برای کنترلر خود در نظر بگیرید.
من نام Controller.js را برای آن انتخاب کرده ام.
زمانبندی اجرا پروژه
زمانی که کنترلر AngularJS ساخته شد میتوانیم ببینیم که به طور پیش فرض کنترلر دارای کد هایی با مدل تعیین شده ی از پیش تعیین شده است.
من قطعه کد بالا را تغییر داده ام. مانند افزودن یک Module و Controller همانند زیر :
اگر بسته ی AngularJS وجود نداشت ، آن را به پروژه تان اضافه کنید.
بر روی پروژه ی MVC خود راست کلیک کنید و گزینه ی Manage NuGet Packegaes را انتخاب کنید. AngularJS را انتخاب کنید و آن را نصب کنید.
حال میتوانیم همه ی بسته های AngularJS که نصب کرده ایم به همراه همه ی فایل ها را در فولدر script را ببینیم.
در زیر روش ایجاد فایل AngularJS Script آورده شده است :
Modules.JS
در اینجا مراجع را به Angular.js JavaScript اضافه میکنیم و Angular Module ای با نام “RESTClientModule”.
reference path="../angular.js" / /// reference path="../angular.min.js" / /// reference path="../angular-animate.js" / /// reference path="../angular-animate.min.js" / var app; (function() { app = angular.module("RESTClientModule", ['ngAnimate']); })();
کنترلر
در کنترلر AngularJS من همه ی منطق کار را انجام داده ام و داده را از Web API به صفحه ی MVC HTML برمیگردانیم.
ابتدا من همه ی متغیر های محلی را برای استفاده اعلام میکنم.
من تنها از یک متد “selectScheduleDetails” استفاده کرده ام. در آن ، متد Web API را با Project ID به عنوان یک پارامتر پاس میدهیم و نتیجه ای که در متغیر AngularJS ذخیره شده است را برای نمایش در صفحه ی MVC HTML برمیگردانیم.
در رویداد کلیک دکمه ی Search من همین متد را با پاس دادن Project ID به عنوان پارامتر جستجو ، پاس میدهم.
app.controller("AngularJs_studentsController", function($scope, $timeout, $rootScope, $window, $http) { $scope.date = new Date(); $scope.projectId = ""; selectScheduleDetails($scope.projectId); function selectScheduleDetails(projectId) { $http.get('/api/schedule/projectScheduleSelect/', { params: { projectId: projectId } }).success(function(data) { $scope.Schedules = data; if ($scope.Schedules.length 0) {} }) .error(function() { $scope.error = "An Error has occured while loading posts!"; }); } //Search $scope.searchScheduleDetails = function() { selectScheduleDetails($scope.projectId); } });
صفحه ی MVC HTML
تمام نتایج نهایی در صفحه ی HTML نمایش داده خواهد شد.
از آنجایی که در اینجا همه نتایج را به طور داینامیک دریافت میکنیم ، نمیتوانیم هیچ مقداری را از پیش در صفحه ی HTML مان تعیین کنیم.
قسمت Header جدول HTML و داده های ما باید به طور داینامیکی نولید شوند.
از آنجایی که احتیاج به نمایش داینامیکی Header و داده ها را داریم من از “ng-repeat” برای نمایش داینامیکی نتایج در Header استفاده میکنم تا از تکراری شدن نتیجه نیز جلوگیری شود.
من محدوده ی نتایج را به نمایش یک عنوان ۱ “limitTo” تنظیم کرده ام.
نکته :
من از {{key}} ابتدا برای نمایش Header و از {{val}} برای نمایش داده های نتیجه استفاده کرده ام.
همانطور که توضیح دادم شما عدد های -۱,۰,۱,۲ در نمایش داده ها در اختیار دارید.
نتیجه ی نهایی در جدول HTML یک نمودار زمانبندی پروژه گرافیکی است.
من از تگ span برای نمایش نتیجه به شیوه ی گرافیکی به عنوان یک نمودار از جدول با رنگ های مشخص شده استفاده میکنم.
table style=" background-color:#FFFFFF; border: solid 2px #6D7B8D; width: 99%;table-layout:fixed;" cellpadding="0" cellspacing="0" tr style="height: 30px; background-color:#336699 ; color:#FFFFFF ;border: solid 1px #659EC7;" ng-repeat="item in Schedules | limitTo:1" td width="80" align="center" ng-repeat="(key, val) in item | limitTo:1" table tr td {{key}} /td /tr /table /td /tr tr style="height: 30px; color:darkred ;border: solid 1px #659EC7;" ng-repeat="item in Schedules" td width="80" style="border: solid 1px #659EC7;table-layout:fixed;padding:0;" align="center" ng-repeat="(key, val) in item" table cellpadding="0" cellspacing="0" tr td align="center" width="60" style="padding:0;" div ng-if="key == 'ProjectName' " {{val}} /div div ng-if="key == 'viewtype' " {{val}} /div div ng-if="key == 'ProjectType' " {{val}} /div div ng-if="val == '0' key != 'ProjectType' " /div div ng-if="val == '1' key != 'ProjectType'" span style="background-color: deepskyblue; width: 100%; float:left; display: inline;margin-right:76px;" /span /div div ng-if="val == '2' key != 'ProjectType'" span style="background-color: limegreen; width: 100%; float:left; display: inline;margin-right:76px;"/span /div div ng-if="val == '-1' key != 'ProjectType'" span style="background-color: red; width: 100%; float:left; display: inline;margin-right:48px;color:white"END/span /div /td /tr /table /td /tr/table
خروجی نهایی زمانبندی اجرا پروژه
خروجی نهایی همانند زیر خواهد بود. همانطور که قبلا گفتم همه ی نتایج نهایی از Stored Procedure با استفاده از وضعیت داده ها دریافت میشوند. من تگ span را در داخل جدول HTML برای نمایش نمودار زمانبندی قرار میدهم.
نتایج واقعی و زمانبندی شده را در داخل جدول HTML نمایش میدهم.
در اینجا میتوانیم ببینیم که برای هر پروژه، من نمودار زمانبندی را با رنگ آبی و تاریخ پایان زمانبندی را با رنگ قرمز و مشابه همان برای هر پروژه ی واقعی تاریخ شروع با رنگ سبز و تاریخ پایان با رنگ قرمز نمایش داده میشود.
در Stored Procedure من هر تاریخ شروع و پایان زمانبندی و واقعی را چک میکنم و نتیجه را به ترتیب هفته ای با وضعیت ۱ برای زمانبندی ها و ۲ برای واقعی ها نمایش میدهیم.
به عنوان مثال اگر نتیجه زیر را از پروژه ی ۱ در نظر بگیریم ، میتوانیم موارد زیر را که در جدول وارد کرده ایم ببینیم :
- تاریخ شروع زمانبندی شده : ۲۰۱۵-۰۶-۰۱ (اگر ما هفته را چک کنیم تاریخ مورد نظر ما هفته ۲۴ خواهد بود)
- تاریخ پایان زمانبندی شده : ۲۰۱۵-۰۹-۰۲ (اگر ما هفته را چک کنیم تاریخ مورد نظر ما هفته ۳۶ خواهد بود)
- تاریخ شروع واقعی : ۲۰۱۵-۰۶-۲۲ (اگر ما هفته را چک کنیم تاریخ مورد نظر ما هفته ۲۷ خواهد بود)
- تاریخ پایان واقعی : ۲۰۱۵-۰۸-۲۶ (اگر ما هفته را چک کنیم تاریخ مورد نظر ما هفته ۳۵ خواهد بود)
در قسمت Stored Procedure میتوانیم نتیجه ی بازه های زمانی هفته ها را مشاهده کنیم.
برای تاریخ های زمانبندی شده با ۱ و تاریخ های واقعی با ۲ نشان داده شده اند.
در صفحه ی MVC HTML من با استفاده از AngularJS ng-repeat و ng-if=”val==’1’1 من تمام نتایج را چک میکنم و همه را در یک نمودار در داخل جدول همانند زیر نمایش میدهم :
زمانبندی اجرا پروژه
نکته : در فایل Webconfig میتوانید Connection را با توجه به نام Connection مربوط به SQL Server خودتان تغییر دهید.
امیدوارم از این مقاله لذت برده باشید.
نظرات و پیشنهاداتتان را با من در میان بگذارید.
موفق باشید!
لینک دانلود ۴۰۴ میزنه
۶
انجام شد
۷
عکسا لود نمیشه
۱۰
اصلاح شد
موفق باشید
لایک