2017-11-21 3 views
1

私はVBで小さなスクリプトを実行しており、startDateとendDateの間にある月だけを表示しようとしています。ここに私のVB + SQLがあります。私はこれがVBの問題ではなく、SQLの問題だと思う。動的ピボット - 必要な場合のみフィールドを表示

Private Sub ChartData_Click(sender As Object, e As EventArgs) Handles ChartData.Click 


    'Initialize the objects before use 
    Dim dataAdapter As New SqlClient.SqlDataAdapter() 
    Dim dataSet As New DataSet 
    Dim command As New SqlClient.SqlCommand 
    Dim datatableMain As New System.Data.DataTable() 
    Dim connection As New SqlClient.SqlConnection 
    Dim DestName As String 
    Dim VBstartDate As Date 
    Dim VBendDate As Date 
    Dim strSql As String 

    MessageBox.Show("Please notice: it may take 1-2 minutes to product your report, depending on the volume of data selected!") 

    'Assign your connection string to connection object 
    connection.ConnectionString = "Data Source=Server-Name;Initial Catalog=DB-Name;Integrated Security=True" 
    command.Connection = connection 
    command.CommandType = CommandType.Text 
    'You can use any command select 

    VBstartDate = DatePickerStart.Value.ToString("MM/dd/yyyy") 
    VBendDate = DatePickerEnd.Value.ToString("MM/dd/yyyy") 

    strSql = "SELECT * FROM (SELECT Contact_ID, TB_Line, Deal_Balance, DATENAME(Month,[AsOfDate]) AS TheDate FROM [TBL_Deposit_HIST] Where [AsOfDate] >= '" & VBstartDate & "' and [AsOfDate] <= '" & VBendDate & "') AS P PIVOT (SUM(DEAL_BALANCE) FOR TheDate in (January, February, March, April, May, June, July, August, September, October, November, December)) AS PV;" 
    command.CommandText = StrSql 
    dataAdapter.SelectCommand = command 

    'Dim f As FolderBrowserDialog = New FolderBrowserDialog 
    Try 
     'If f.ShowDialog() = DialogResult.OK Then 
     'This section help you if your language is not English. 
     System.Threading.Thread.CurrentThread.CurrentCulture = 
      System.Globalization.CultureInfo.CreateSpecificCulture("en-US") 
     Dim oExcel As Excel.Application 
     Dim oBook As Excel.Workbook 
     Dim oSheet As Excel.Worksheet 
     Dim oRange As Excel.Range 

     oExcel = CreateObject("Excel.Application") 
     oBook = oExcel.Workbooks.Add(Type.Missing) 
     oSheet = oBook.Worksheets(1) 
     'oRange = oExcel.Range 

     Dim columnLetter As String 
     Dim dc As System.Data.DataColumn 
     Dim dr As System.Data.DataRow 
     Dim colIndex As Integer = 0 
     Dim rowIndex As Integer = 0 

     'Fill data to datatable 
     connection.Open() 
      dataAdapter.Fill(datatableMain) 
      connection.Close() 


      'Export the Columns to excel file 
      For Each dc In datatableMain.Columns 
       colIndex = colIndex + 1 
       oSheet.Cells(1, colIndex) = dc.ColumnName 
      Next 

      'Export the rows to excel file 
      For Each dr In datatableMain.Rows 
       rowIndex = rowIndex + 1 
       colIndex = 0 
       For Each dc In datatableMain.Columns 
        colIndex = colIndex + 1 
        oSheet.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName) 
       Next 
      Next 

     Dim LastRow As Long 
     Dim LastColumn As Long 
     Dim StrLastCol As String 

     ' Find last row and last column 
     With oSheet 
      LastRow = .Cells(.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row 
      LastColumn = .Cells(1, .Columns.Count).End(Excel.XlDirection.xlToLeft).Column 
     End With 

     ' Convert column number to column letter 
     Select Case LastColumn 
      Case 1 To 26 
       StrLastCol = Convert.ToChar(Convert.ToInt32("A"c) + LastColumn - 1).ToString() 
      Case 27 To 52 
       StrLastCol = Convert.ToChar(Convert.ToInt32("a"c) + LastColumn - 27).ToString() 
      Case Else 
       StrLastCol = String.Empty 
     End Select 

     'create chart object 
     Dim chartPage As Excel.Chart 
     Dim xlCharts As Excel.ChartObjects 
     Dim myChart As Excel.ChartObject 
     Dim chartRange As Excel.Range 

     xlCharts = oSheet.ChartObjects 
     myChart = xlCharts.Add(10, 80, 300, 250) 
     chartPage = myChart.Chart 

     ' Set dynamic range 
     chartRange = oSheet.Range("A1:" & StrLastCol & "25") 
     chartPage.SetSourceData(Source:=chartRange) 
     chartPage.ChartType = Excel.XlChartType.xlColumnClustered 

     'Set final path for saving Excel Report 
     DestName = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\Report.xls" 

     oExcel.Visible = True 
     oSheet.Columns.AutoFit() 
     'Save file in final path 
     oBook.SaveAs(DestName, XlFileFormat.xlWorkbookNormal, Type.Missing, 
      Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive, 
      Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing) 


     'Release the objects 
     ReleaseObject(oSheet) 
      oBook.Close(False, Type.Missing, Type.Missing) 
      ReleaseObject(oBook) 
      oExcel.Quit() 
      ReleaseObject(oExcel) 
      'Some time Office application does not quit after automation: 
      'so i am calling GC.Collect method. 
      GC.Collect() 

     MessageBox.Show("Export done successfully! You can find your report on your desktop!!") 

     'End If 
    Catch ex As Exception 
     MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK) 
    End Try 

End Sub 

たとえば、これは近いと思われます。

DECLARE @cols AS NVARCHAR(MAX), 
     @query AS NVARCHAR(MAX); 
declare @startDate datetime 
declare @endDate datetime   
set @startDate = '10/10/2017' 
set @endDate = '11/30/2017' 
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.AsOfDate) 
      FROM [TBL_Deposit_HIST] c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT Contact_ID, ' + @cols + ' from 
      (
       SELECT Contact_ID, 
       Deal_Balance, 
       AsOfDate 
       from [TBL_Deposit_HIST] 
      ) x 
      pivot 
      (
       SUM(Deal_Balance) 
       WHERE AsOfDate BETWEEN (' + @cols + ') AND (' + @cols + ') 
      ) p ' 
execute(@query) 

ただし、これにより次のエラーが発生します。

Msg 156, Level 15, State 1, Line 11 
Incorrect syntax near the keyword 'WHERE'. 

以下のスクリプトはコンパイルされますが、日付範囲が広すぎます。

DECLARE @cols AS NVARCHAR(MAX), 
     @query AS NVARCHAR(MAX); 
declare @startDate datetime 
declare @endDate datetime   
set @startDate = '10/10/2017' 
set @endDate = '11/30/2017' 
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.AsOfDate) 
      FROM [TBL_Deposit_HIST] c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT Contact_ID, ' + @cols + ' from 
      (
       SELECT Contact_ID, 
       Deal_Balance, 
       AsOfDate 
       from [TBL_Deposit_HIST] 
      ) x 
      pivot 
      (
       SUM(Deal_Balance) 
       for AsOfDate in (' + @cols + ') 

      ) p ' 
execute(@query) 

私はどこでもとBetweenが必要だと思っていますが、正しく動作させることはできません。

結果はExcelで表示されます。 DatePickerはうまく動作し、SQLは文字通り何をするかを指示しますが、私が選択したとしても、すべての月が表示されます。9/1/17から11/20/17としましょう。ダイナミックな日付とともにピボットフィールドをダイナミックにする方法がありますか?または、そのまま実行して、行2が空のExcelの列を削除するか、そのようなものを削除する必要がありますか?私はstartDateとendDateの間にデータだけを表示したい。ありがとう。

答えて

0

選択してWHERE句を含めない:

SELECT Contact_ID, 
       Deal_Balance, 
       AsOfDate 
from [TBL_Deposit_HIST] 
WHERE AsOfDate BETWEEN (' + @cols + ') AND (' + @cols + ') 

...動作しませんか?

+0

私は投稿する前にそれを試みました。私はそれはうまくいくだろうが、私はこれを得る:キーワードの近くに誤った構文 'WHERE'。 – ryguy72

+0

ありがとうモナ。それが解決策になるかもしれないようです。私の特定のシナリオに合うようにコードを適応させる手助けはできますか?私はいくつかのことを試みましたが、それを働かせることはできませんでした。ありがとう。 – ryguy72

1

2つの日付の間の月を表示したい場合は、日付が25 Nov 2017から15 Mar 2018になる場合があるため、年を含めるようにしてください。

私は@start@end間のすべての月の列を構築し、あなただけの正確なを見つけることによって、これを省略することができます[yyyy-MMM]

説明

  1. と月が表示されますサンプルデータを設計しwhere句を使用してテーブルにクエリを適用することによって使用される月。
  2. あなたのテーブルから[yyyy-MMM]として日付をフォーマットすると、すべてのデータを取得し、このために私はピボット

クエリ

if exists(select 1 from #data) 
    drop table #data 
create table #data(
    Id int not null identity(1,1), 
    AsOfDate datetime, 
    Balance money 
) 

insert into #data(AsOfDate,Balance) 
values ('11 Oct 2017',1854.24), 
     ('15 Sep 2017',1554.25), 
     ('11 Sep 2017',1554.14), 
     ('09 May 2017',255.55), 
     ('27 Sep 2017',145.15) 

    declare @start datetime = '05 May 2017', 
      @end datetime ='17 Sep 2017' 

declare @cols varchar(max), 
     @query varchar(max); 

with months as(
    select @start as [Date], quotename(format(@start,'yyyy MMM')) as [Month] 
    union all 
    select dateadd(month,1,[Date]),quotename(format(dateadd(month,1,[Date]),'yyyy MMM')) 
    from months 
    where [Date] < @end 
) 

select @cols = stuff((select ',' + [Month] 
        from months 
        order by [Date] 
        for xml path(''),type).value('.','nvarchar(max)'),1,1,'') 


select @query = ';with report as(
       select sum(Balance) [Balance],format(AsOfDate,''yyyy MMM'') as [Date] 
       from #data 
       where AsOfDate between ''' + cast(@start as varchar) + ''' and ''' + cast(@end as varchar) + ''' 
       group by format(AsOfDate,''yyyy MMM'')) 
      select ' + @cols + ' 
      from report 
      pivot(sum(Balance) for [Date] in('+ @cols +')) p' 

exec (@query)  

出力結果

を適用 report CTE
  • を使用
    2017 May 2017 Jun 2017 Jul 2017 Aug 2017 Sep 2017 Oct 
    255.55 NULL NULL NULL 3108.39 NULL 
    

    希望すると、これはあなたに役立ちます

  • 関連する問題