Ask a questionAsk a question
 

AnswerManipulating RDLC at runtime

  • Wednesday, September 27, 2006 5:50 PMWil Burton Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    On all my reports I can manipulate the RDLC at runtime using XML.  I have run into a problem, however.

    On this one report, I have a hyperlink, but in some cases I don't want it to link at all.  If I change the report name to blank, it still acts like a link.  Since there is no expression to set to make it change to 'None', I figure my only choice is to manipulate the XML before loading the report.

    Here is the RDLC:


    <Textbox Name="MenuItemDesc">
      <
    Left>0.1875in</Left>
     
    <rd:DefaultName>MenuItemDesc</rd:DefaultName>
      <
    ZIndex>9</ZIndex>
      <
    Action>
        <
    Drillthrough>
          <
    ReportName>=Parameters!StoreID.Value &amp; ";" &amp; Fields!InvItemID.Value</ReportName>
        </
    Drillthrough>
      </
    Action>
      <
    Width>1.375in</Width>
      <
    Style>
        <
    FontFamily>Tahoma</FontFamily>
        <
    FontSize>7pt</FontSize>
        <
    Color>=IIf(Parameters!StoreID.Value = 0, "Black", "Blue")</Color>
      </
    Style>
      <
    Value>=Fields!Description.Value</Value>
    </
    Textbox>

    Here is the code I am using:


    Private Sub DisableLinks(ByVal reportStream As IO.Stream)
    '// Load into xml document
    Dim reportDocument As New Xml.XmlDocument
    reportDocument.Load(reportStream)

    Dim manager As New Xml.XmlNamespaceManager(reportDocument.NameTable)
    manager.AddNamespace(
    "rdl", http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition)
    manager.AddNamespace(
    "rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")

    '// Remove action node
    Dim actionNode As Xml.XmlNode = reportDocument.SelectSingleNode("//rdl:Textbox[@Name = 'MenuItemDesc']/rdl:Action", manager)
    actionNode.ParentNode.RemoveChild(actionNode) 

    '// Save it back to report stream
    reportStream.Position = 0
    reportDocument.Save(reportStream)
    reportStream.Position = 0

    End Sub

     I get this error:


    An error occurred during local report processing.

    Inner Exception:
    "The definition of the report 'Main Report' is invalid."
    "The report definition is not valid.  Details: Data at the root level is invalid. Line 1082, position 10."

Answers

  • Wednesday, September 27, 2006 7:01 PMWil Burton Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    I figured it out.  I was saving the XML back into the stream, but since it was smaller, the stream still contained the remnants of the previous XML.

    I just had to set the stream to a New MemoryStream.

All Replies

  • Wednesday, September 27, 2006 5:59 PMWil Burton Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Also, if I change anything in this node i get an error.  I can change the Value element without problems though.  This is very troubling.
  • Wednesday, September 27, 2006 7:01 PMWil Burton Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    I figured it out.  I was saving the XML back into the stream, but since it was smaller, the stream still contained the remnants of the previous XML.

    I just had to set the stream to a New MemoryStream.

  • Wednesday, September 27, 2006 8:11 PMNoemie Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    How do you manage to have your reportStream ?
  • Thursday, October 29, 2009 6:46 PMWil Burton Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Pass the full namespace of the RDLC that is in your project ("YourApp.Reports.SomeReport.rdlc")

        Protected Function GetReportStream(ByVal resourceName As String) As IO.MemoryStream

          Dim manifestStream As IO.Stream = Me.GetType.Assembly.GetManifestResourceStream(resourceName)
          Dim reportStream As IO.MemoryStream = CopyStream(manifestStream)
          reportStream.Position = 0


          Return reportStream

        End Function

        Private Function CopyStream(ByVal stream As IO.Stream) As IO.MemoryStream

          Dim copy As New IO.MemoryStream

          Dim buffer(32768) As Byte
          Dim bytesRead As Int32

          bytesRead = stream.Read(buffer, 0, buffer.Length)

          While bytesRead > 0
            copy.Write(buffer, 0, bytesRead)
            bytesRead = stream.Read(buffer, 0, buffer.Length)

          End While
          copy.Flush()
          copy.Position = 0


          Return copy

        End Function