33

SQL Server Reporting Services レポートを展開するための反復可能なプロセスを作成する必要があります。私は、これを行うために Visual Studio や Business Development Studio を使用することに賛成ではありません。展開をスクリプト化する rs.exe の方法も、かなり扱いにくいようです。レポートを展開できる非常に洗練された方法を持っている人はいますか? ここで重要なのは、プロセスを完全に自動化することです。

4

7 に答える 7

33

rs.exe を使用します。スクリプトを作成したら、もう触る必要はありません。動作するだけです。

ソースは次のとおりです (テストする機会なしに機密データを削除するために手動でわずかに変更しました。何もブレーキしないことを願っています)。さまざまな言語のサブディレクトリからレポートと関連する画像を展開します。また、データソースが作成されます。

'=====================================================================
'  File:      PublishReports.rss
'
'  Summary: Script that can be used with RS.exe to 
'           publish the reports.
'
'  Rss file spans from beginnig of this comment to end of module
' (except of "End Module").
'=====================================================================

Dim langPaths As String() = {"en", "cs", "pl", "de"}
Dim filePath As String = Environment.CurrentDirectory

Public Sub Main()

    rs.Credentials = System.Net.CredentialCache.DefaultCredentials

    'Create parent folder
    Try
        rs.CreateFolder(parentFolder, "/", Nothing)
        Console.WriteLine("Parent folder created: {0}", parentFolder)
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try

    PublishLanguagesFromFolder(filePath)

End Sub

Public Sub PublishLanguagesFromFolder(ByVal folder As String)
    Dim Lang As Integer
    Dim langPath As String

    For Lang = langPaths.GetLowerBound(0) To langPaths.GetUpperBound(0)
        langPath = langPaths(Lang)

        'Create the lang folder
        Try
            rs.CreateFolder(langPath, "/" + parentFolder, Nothing)
            Console.WriteLine("Parent lang folder created: {0}", parentFolder + "/" + langPath)
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

        'Create the shared data source
        CreateDataSource("/" + parentFolder + "/" + langPath)

        'Publish reports and images
        PublishFolderContents(folder + "\" + langPath, "/" + parentFolder + "/" + langPath)
    Next 'Lang
End Sub

Public Sub CreateDataSource(ByVal targetFolder As String)
    Dim name As String = "data source"

    'Data source definition.
    Dim definition As New DataSourceDefinition
    definition.CredentialRetrieval = CredentialRetrievalEnum.Store
    definition.ConnectString = "data source=" + dbServer + ";initial catalog=" + db
    definition.Enabled = True
    definition.EnabledSpecified = True
    definition.Extension = "SQL"
    definition.ImpersonateUser = False
    definition.ImpersonateUserSpecified = True
    'Use the default prompt string.
    definition.Prompt = Nothing
    definition.WindowsCredentials = False
    'Login information
    definition.UserName = "user"
    definition.Password = "password"

    Try
    'name, folder, overwrite, definition, properties 
        rs.CreateDataSource(name, targetFolder, True, definition, Nothing)
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try

End Sub

Public Sub PublishFolderContents(ByVal sourceFolder As String, ByVal targetFolder As String)
    Dim di As New DirectoryInfo(sourceFolder)
    Dim fis As FileInfo() = di.GetFiles()
    Dim fi As FileInfo

    Dim fileName As String

    For Each fi In fis
        fileName = fi.Name
        Select Case fileName.Substring(fileName.Length - 4).ToUpper
            Case ".RDL"
                PublishReport(sourceFolder, fileName, targetFolder)
            Case ".JPG", ".JPEG"
                PublishResource(sourceFolder, fileName, "image/jpeg", targetFolder)
            Case ".GIF", ".PNG", ".BMP"
                PublishResource(sourceFolder, fileName, "image/" + fileName.Substring(fileName.Length - 3).ToLower, targetFolder)
        End Select
    Next fi
End Sub

Public Sub PublishReport(ByVal sourceFolder As String, ByVal reportName As String, ByVal targetFolder As String)
    Dim definition As [Byte]() = Nothing
    Dim warnings As Warning() = Nothing

    Try
        Dim stream As FileStream = File.OpenRead(sourceFolder + "\" + reportName)
        definition = New [Byte](stream.Length) {}
        stream.Read(definition, 0, CInt(stream.Length))
        stream.Close()
    Catch e As IOException
        Console.WriteLine(e.Message)
    End Try

    Try
   'name, folder, overwrite, definition, properties 
        warnings = rs.CreateReport(reportName.Substring(0, reportName.Length - 4), targetFolder, True, definition, Nothing)

        If Not (warnings Is Nothing) Then
            Dim warning As Warning
            For Each warning In warnings
                Console.WriteLine(warning.Message)
            Next warning
        Else
            Console.WriteLine("Report: {0} published successfully with no warnings", targetFolder + "/" + reportName)
        End If
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try
End Sub

Public Sub PublishResource(ByVal sourceFolder As String, ByVal resourceName As String, ByVal resourceMIME As String, ByVal targetFolder As String)
    Dim definition As [Byte]() = Nothing
    Dim warnings As Warning() = Nothing

    Try
        Dim stream As FileStream = File.OpenRead(sourceFolder + "\" + resourceName)
        definition = New [Byte](stream.Length) {}
        stream.Read(definition, 0, CInt(stream.Length))
        stream.Close()
    Catch e As IOException
        Console.WriteLine(e.Message)
    End Try

    Try
    'name, folder, overwrite, definition, MIME, properties 
        rs.CreateResource(resourceName, targetFolder, True, definition, resourceMIME, Nothing)
        Console.WriteLine("Resource: {0} with MIME {1} created successfully", targetFolder + "/" + resourceName, resourceMIME)
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try
End Sub

rs.exe を呼び出すバッチは次のとおりです。

SET ReportServer=%1
SET DBServer=%2
SET DBName=%3
SET ReportFolder=%4

rs -i PublishReports.rss -s %ReportServer% -v dbServer="%DBServer%" -v db="%DBName%" -v parentFolder="%ReportFolder%" >PublishReports.log 2>&1

pause
于 2008-09-18T09:04:57.777 に答える
8

@Davidが提供するスクリプトを使用しましたが、コードを追加する必要がありました(コメントするには長すぎるため、これを回答として入力しています。

問題は、レポート定義のレポートに「共有データソース」がすでに添付されている場合、これがスクリプトで作成されたものと同じデータソースになることは決してないということです。

これは、「CreateReport」メソッドによって発行された警告からも明らかになります。

データセット''は、レポートサーバーで公開されていない共有データソース''を参照します。

したがって、データソースは後で明示的に設定する必要があります。次のコード変更を行いました。

グローバル変数を追加しました:

Dim dataSourceRefs(0) As DataSource

CreateDataSourceメソッドの最後に、その変数が入力されます。

Dim dsr As New DataSourceReference
dsr.Reference = "/" + parentFolder + "/" + db
Dim ds As New DataSource
ds.Item = CType(dsr, DataSourceDefinitionOrReference)
ds.Name = db
dataSourceRefs(0) = ds

また、PublishReportメソッドでは、そのデータソースが明示的に設定されます(CreateReportが呼び出された後)。

rs.SetItemDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)

この最後の呼び出しはRS2005以降のみであることに注意してください。レポートをRS2000サーバーにロードする場合は、代わりにSetReportDataSourcesを使用する必要があります。

rs.SetReportDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)
于 2010-05-03T15:39:19.110 に答える
1

まあ、本当にエレガントではありません。私たちは、reportingservices2005 Web サービスを使用する独自のツールを作成しました。これが、私たちが望むものを得る最も信頼できる方法であることがわかりました.

それほど難しいことではなく、必要に応じてデータ ソースやフォルダーの作成など、他のことを行うために拡張できます。

于 2008-09-17T23:41:39.253 に答える
1

RSScripterを強くお勧めします。概要で述べたように:

Reporting Services Scripter は .NET Windows Forms アプリケーションで、すべての Microsoft SQL Server Reporting Services カタログ アイテムのスクリプト作成と転送を可能にして、あるサーバーから別のサーバーへの転送を支援します。また、同じサーバー上の 1 つの Reporting Services フォルダーから別のフォルダーに大量のアイテムを簡単に移動するためにも使用できます。選択したスクリプト オプションに応じて、Reporting Services Scripter は、説明、履歴オプション、実行オプション (レポート固有および共有スケジュールを含む)、サブスクリプション (通常およびデータ ドリブン)、サーバー側レポート パラメーターなど、すべてのカタログ アイテム プロパティも転送できます。

于 2010-04-16T07:12:58.583 に答える
0

Business Development Studio でこれを行うことに賛成ではないとおっしゃっていることは承知していますが、組み込みツールは非常に信頼性が高く、使いやすいことがわかりました。

于 2008-09-17T23:38:05.767 に答える
0

CruiseControl.NET などの継続的インテグレーション ソリューションを検討しましたか? rs.exe を使用してレポートを展開できる場合は、CruiseControl で自動化されたプロセスをセットアップして、タイマーで、またはレポートが変更されるたびにレポートを作成および展開できます。

于 2008-09-18T00:18:52.800 に答える