Добавление чередующегося цвета строки в отчет служб отчетов SQL Server

142

Как затенять чередующиеся строки в отчете служб отчетов SQL Server?


Изменить: Ниже перечислены несколько хороших ответов - от быстрых и простых до сложных и исчерпывающих . Увы, я могу выбрать только одно ...

Майкл Харен
источник
2
= IIf (RowNumber (Nothing) Mod 2 = 0, «No Color», «# DDEBF7»)
Стефан Штайгер,
Если вы выберете несколько ячеек, вы не сможете редактировать свойства текстового поля, но вы можете получить доступ к цвету заливки на панели свойств и установить там выражение!
kitsu.eb 03

Ответы:

213

Перейдите к свойству BackgroundColor строки таблицы и выберите «Выражение ...»

Используйте это выражение:

= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")

Этот прием можно применить ко многим областям отчета.

А в .NET 3.5+ вы можете использовать:

= If(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")

Не ищу представителя - я просто исследовал этот вопрос сам и подумал, что поделюсь.

Майкл Харен
источник
10
Это не удается при определенных обстоятельствах, особенно в таблицах и объектах матриц с большим количеством промежуточных итогов. Ответ Catch22 не имеет таких же ограничений. Кроме того, метод Catch22 можно использовать, чтобы заставить столбцы в матрице иметь чередующиеся цвета столбцов, что полезно один раз в синюю луну.
Зарегистрированный пользователь
16
Я всегда уверен, что проголосую за того, кто отвечает на их собственный вопрос. Слишком часто спрашивающий находит ответ самостоятельно и никогда не возвращается, чтобы опубликовать его, оставляя всех нас, у кого может быть тот же вопрос, в неведении. Шишка для вас, сэр.
Мэтт Дитролио
4
Когда я использую приведенный выше код, я получаю предупреждающее сообщение вроде " [rsInvalidColor] The value of the BackgroundColor property for the textbox ‘active’ is “Transparent”, which is not a valid BackgroundColor. Похоже, правильное выражение будет" =IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing). Тем не менее, спасибо за совет.
Russell B
2
Это создает проблему в случае группировки и просмотра подробностей
3
некоторые браузеры не могут обрабатывать "Прозрачный" или "Ничего". Лучше всего было бы использовать «белых»
Нейт С.
89

Использование IIF (RowNumber ...) может привести к некоторым проблемам при группировке строк, и другой альтернативой является использование простой функции VBScript для определения цвета.

Это немного больше усилий, но когда базового решения недостаточно, это хорошая альтернатива.

По сути, вы добавляете код в отчет следующим образом ...

Private bOddRow As Boolean
'*************************************************************************
' -- Display green-bar type color banding in detail rows
' -- Call from BackGroundColor property of all detail row textboxes
' -- Set Toggle True for first item, False for others.
'*************************************************************************
Function AlternateColor(ByVal OddColor As String, _
         ByVal EvenColor As String, ByVal Toggle As Boolean) As String
    If Toggle Then bOddRow = Not bOddRow
    If bOddRow Then
        Return OddColor
    Else
        Return EvenColor
    End If
End Function

Затем для каждой ячейки установите BackgroundColor следующим образом:

=Code.AlternateColor("AliceBlue", "White", True)

Полная информация находится в этой статье Wrox

Словить 22
источник
Приведенный выше код либо добавляется в раздел отчета «Код», либо на страницу кода программной части в проекте VB.NET, компилируется и развертывается как DLL, на которую имеется ссылка как на сборку. Я рекомендую приложить дополнительные усилия для развертывания этого как dll, поскольку вы обычно упоминаете об этом в многочисленных отчетах.
Зарегистрированный пользователь
Это мой предпочтительный способ решения проблемы группировки после нескольких попыток взлома. Он не ломается, когда к столбцу применяется интерактивная сортировка. +1 и большое спасибо.
Рекс Миллер,
Цвета смещаются, если у вас нечетное количество строк.
K Richard
20
Не забудьте изменить «True» на «False» для всех столбцов в строке после первого, иначе вы увидите эффект шахматной доски! Спасибо за решение - отлично работает!
Питер Мулариен,
Питер Мулариен: У меня возникла эта проблема, вы можете объяснить, как ее исправить?
Bill Software Engineer
66

Я получил шахматный эффект, когда использовал решение Catch22, я думаю, потому что моя матрица имеет более одного столбца в дизайне. это выражение отлично сработало для меня:

=iif(RunningValue(Fields![rowgroupfield].Value.ToString,CountDistinct,Nothing) Mod 2,"Gainsboro", "White")
ахмад
источник
13
Этот ответ заслуживает гораздо большего внимания - это чистое решение, которое отлично работает в матрице с группами строк и группами столбцов и не требует для работы специального кода. Красивая!
Stefan Mohr
9
На самом деле, это прекрасно работает даже для нескольких столбцов, но не в том случае, если у вас есть «недостающие» данные в группе. Таким образом, если у вас есть данные, которые содержат данные за 12 месяцев в 2007 году, но отсутствуют данные за январь в 2006 году и сгруппированы по месяцам в строках и году в столбцах, окраска 2006 года будет отключена на единицу, потому что RunningValue выходит из синхронизации, потому что даже при наличии все еще поле в матрице для «Январь 2006», в наборе данных нет данных, а RunningValue остается прежним, без изменения цвета и т. д.
Кайл Хейл
2
@ahmad это так близко. У меня проблема, когда пустые поля имеют противоположный цвет. как убедиться, что пустые коробки правильно окрашены?
FistOfFury 02
@KyleHale, у вас есть исправление для отсутствующей окраски коробки?
FistOfFury 02
2
@FistOfFury Единственное известное мне решение - установить значение (обычно 0) для отсутствующих данных.
Кайл Хейл
20

Я изменил решение @Catch22. Мне не нравится идея заходить в каждое поле, если я решу, что хочу изменить один из цветов. Это особенно важно в отчетах, где необходимо изменить цветовую переменную в многочисленных полях.

'*************************************************************************
' -- Display alternate color banding (defined below) in detail rows
' -- Call from BackgroundColor property of all detail row textboxes
'*************************************************************************
Function AlternateColor(Byval rowNumber as integer) As String
    Dim OddColor As String = "Green"
    Dim EvenColor As String = "White"

    If rowNumber mod 2 = 0 then 
        Return EvenColor
    Else
        Return OddColor
    End If
End Function

Заметил, что я изменил функцию с той, которая принимает цвета, на ту, которая содержит цвета, которые будут использоваться.

Затем в каждое поле добавьте:

=Code.AlternateColor(rownumber(nothing))

Это намного надежнее, чем изменение цвета фона каждого поля вручную.

Майкл Икинс
источник
1
Приятное дополнение к этой теме! Мне нравится не указывать «Истина» или «Ложь» в каждом столбце. Мне также нравится вариант «мод 3», поэтому я могу заштриховать только каждый 3-й ряд.
Baodad
Мне тоже нравится это решение. Однако у меня это не работает, когда я использую группировку строк. Решение @ahmad выше сработало для меня.
Baodad
Это отличное решение для табликса, если вы не хотите добавлять дополнительные поля в свой DataSet!
clamchoda 08
16

Я заметил одну вещь: ни один из двух верхних методов не знает, какого цвета должна быть первая строка в группе; группа просто начнется с цветом, противоположным последней строке предыдущей группы. Я хотел, чтобы мои группы всегда начинались с одного цвета ... первый ряд каждой группы всегда должен быть белым, а следующий - цветным.

Основная идея заключалась в том, чтобы сбрасывать переключатель при запуске каждой группы, поэтому я добавил немного кода:

Private bOddRow As Boolean
'*************************************************************************
' -- Display green-bar type color banding in detail rows
' -- Call from BackGroundColor property of all detail row textboxes
' -- Set Toggle True for first item, False for others.
'*************************************************************************
Function AlternateColor(ByVal OddColor As String, _
         ByVal EvenColor As String, ByVal Toggle As Boolean) As String
    If Toggle Then bOddRow = Not bOddRow
    If bOddRow Then
        Return OddColor
    Else
        Return EvenColor
    End If
End Function
'
Function RestartColor(ByVal OddColor As String) As String
    bOddRow = True
    Return OddColor
End Function

Итак, у меня есть три разных типа фона ячеек:

  1. Первый столбец строки данных имеет = Code.AlternateColor ("AliceBlue", "White", True) (это то же самое, что и в предыдущем ответе.)
  2. Остальные столбцы строки данных имеют = Code.AlternateColor ("AliceBlue", "White", False) (Это также то же самое, что и предыдущий ответ.)
  3. Первый столбец группирующей строки имеет = Code.RestartColor ("AliceBlue") (это новинка.)
  4. Остальные столбцы группирующей строки имеют = Code.AlternateColor ("AliceBlue", "White", False) (Это использовалось раньше, но не упоминалось об этом для группировки строки.)

У меня это работает. Если вы хотите, чтобы группирующая строка была неокрашенной или другого цвета, из этого должно быть довольно очевидно, как ее изменить.

Не стесняйтесь добавлять комментарии о том, что можно сделать для улучшения этого кода: я новичок как в SSRS, так и в VB, поэтому я сильно подозреваю, что есть много возможностей для улучшения, но основная идея кажется разумной (и она была полезной. для меня) поэтому я хотел выкинуть это здесь.

Беска
источник
Вы также можете сбросить нумерацию строк для каждой группы, как описано в этом ответе .
StackOverthrow
10

для верхних и нижних колонтитулов групп:

=iif(RunningValue(*group on field*,CountDistinct,"*parent group name*") Mod 2,"White","AliceBlue")

Вы также можете использовать это для «сброса» счетчика цветов строки в каждой группе. Я хотел, чтобы первая строка деталей в каждой подгруппе начиналась с белого цвета, и это решение (при использовании в строке деталей) позволило это осуществить:

=IIF(RunningValue(Fields![Name].Value, CountDistinct, "NameOfPartnetGroup") Mod 2, "White", "Wheat")

См .: http://msdn.microsoft.com/en-us/library/ms159136(v=sql.100).aspx

Джон Сондерс
источник
8

Решение Майкла Харена отлично подходит для меня. Однако я получил предупреждение о том, что «Transparent» не является допустимым BackgroundColor при предварительном просмотре. Нашел быстрое исправление в настройке BackgroundColor элементов отчета в SSRS . Используйте Nothing вместо "Transparent"

= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing)
Nonetaku
источник
У белых было бы лучше, чем Ничего.
Nate S.
6

Единственный эффективный способ решить эту проблему без использования VB - это «сохранить» значение группировки строк по модулю внутри группировки строк (и вне группировки столбцов) и явно ссылаться на нее внутри группы столбцов. Я нашел это решение в

http://ankeet1.blogspot.com/2009/02/alternating-row-background-color-for.html

Но Ankeet не лучшим образом объясняет, что происходит, и его решение рекомендует ненужный шаг по созданию группировки по постоянному значению, поэтому вот мой пошаговый процесс для матрицы с одной группой строк RowGroup1:

  1. Создайте новый столбец в RowGroup1. Переименуйте текстовое поле для этого во что-то вроде RowGroupColor.
  2. Установите значение текстового поля RowGroupColor на

    =iif(RunningValue(Fields![RowGroupField].Value ,CountDistinct,Nothing) Mod 2, "LightSteelBlue", "White")

  3. Установите для свойства BackgroundColor всех ячеек строки значение

    "=ReportItems!RowGroupColor.Value"

  4. Установите ширину столбца RowGroupColor на 0pt и установите CanGrow на false, чтобы скрыть его от клиентов.

Вуаля! Это также решает многие проблемы, упомянутые в этой теме:

  • Автоматический сброс для подгрупп: Просто добавьте новый столбец для этого rowgroup, выполняя RunningValue на своих групповых ценностях.
  • Не нужно беспокоиться о переключателях True / False.
  • Цвета хранятся только в одном месте для облегчения модификации.
  • Может использоваться взаимозаменяемо в группах строк или столбцов (просто установите высоту на 0 вместо ширины)

Было бы здорово, если бы SSRS предоставляла свойства помимо Value в текстовых полях. Вы можете просто поместить такой вид вычислений в свойство BackgroundColor текстовых полей группы строк, а затем ссылаться на него как на ReportItems! RowGroup.BackgroundColor во всех других ячейках.

Ну что ж, мы можем мечтать ...

Кайл Хейл
источник
5

Моя проблема заключалась в том, что я хотел, чтобы все столбцы в строке имели одинаковый фон. Я сгруппировал как по строкам, так и по столбцам, и с двумя верхними решениями здесь я получил все строки в столбце 1 с цветным фоном, все строки в столбце 2 с белым фоном, все строки в столбце 3 с цветным фоном , и так далее. Это как если бы RowNumberи bOddRow(в решении Catch22) обращали внимание на мою группу столбцов вместо того, чтобы игнорировать это и только чередовать с новой строкой.

Я хотел, чтобы все столбцы в строке 1 имели белый фон, затем все столбцы в строке 2 имели цветной фон, затем все столбцы в строке 3 имели белый фон и так далее. Я получил этот эффект, используя выбранный ответ, но вместо перехода Nothingк нему RowNumberя передал имя своей группы столбцов, например

=IIf(RowNumber("MyColumnGroupName") Mod 2 = 0, "AliceBlue", "Transparent")

Думал, что это может быть полезно кому-то другому.

Сара Сосуды
источник
4

Думаю, здесь этот трюк не обсуждается. Итак, вот оно,

В любой сложной матрице, когда вам нужны альтернативные цвета ячеек, по строкам или по столбцам, рабочее решение:

Если вам нужен другой цвет ячеек по колонке, тогда,

  1. В правом нижнем углу представления дизайна отчета в «Группы столбцов» создайте поддельную родительскую группу на 1 (используя выражение) с именем «FakeParentGroup».
  2. Затем в дизайне отчета для ячеек, которые должны быть окрашены поочередно, используйте следующее выражение цвета фона

= IIF (RunningValue (Fields! [ColumnGroupField] .Value, countDistinct, «FakeParentGroup») MOD 2, «Белый», «Светло-серый»)

Вот и все.

То же самое для строки с альтернативным цветом, просто вам нужно соответствующим образом отредактировать решение.

ВНИМАНИЕ: Здесь иногда нужно соответственно установить границу ячеек, обычно она исчезает.

Также не забудьте удалить значение 1 в отчете, который появился на картинке при создании поддельной родительской группы.

Адитья
источник
1
Этот ответ определенно станет отличной находкой для тех, кому нужно создавать чередование строк в сложных табликсах! Если существует родительская группа, используйте ее. В противном случае создайте FakeParentGroup. Отсутствующие значения в таблицах с группами столбцов и строк обычно нарушают форматирование. См. Мой ответ, основанный на @ Aditya, чтобы учесть недостающие значения в первой ячейке.
рпыж
2

Если для всего отчета вам нужен чередующийся цвет, вы можете использовать DataSet, к которому привязан ваш Tablix, для номера строки идентификации всего отчета в отчете и использовать его в функции RowNumber ...

=IIf(RowNumber("DataSet1")  Mod 2 = 1, "White","Blue")
Мэтт
источник
2

Ответ @ Aditya отличный, но есть случаи, когда форматирование будет сброшено, если самая первая ячейка строки (для форматирования фона строки) имеет пропущенное значение (в сложных таблицах с группами столбцов / строк и пропущенными значениями).

Решение @ Aditya умело использует countDistinctрезультат runningValueфункции для определения номеров строк в группе табликса (строки). Если у вас есть строки табликса с отсутствующим значением в первой ячейке, результат runningValueне будет увеличиваться, countDistinctа будет возвращен номер предыдущей строки (и, следовательно, повлияет на форматирование этой ячейки). Чтобы учесть это, вам нужно будет добавить дополнительный член для компенсации countDistinctзначения. Я решил проверить первое текущее значение в самой группе строк (см. Строку 3 фрагмента ниже):

=iif(
    (RunningValue(Fields![RowGroupField].Value, countDistinct, "FakeOrRealImmediateParentGroup")
    + iif(IsNothing(RunningValue(Fields![RowGroupField].Value, First, "GroupForRowGroupField")), 1, 0)
    ) mod 2, "White", "LightGrey")

Надеюсь это поможет.

рпыж
источник
Спасибо @rpyzh, это было решение, которое сработало для моей многострочной группы с общим отчетом родительской группы строк!
Niallty 06
1

Может ли кто-нибудь объяснить логику превращения остальных полей в false в коде ниже (из сообщения выше)

Я заметил одну вещь: ни один из двух верхних методов не имеет никакого представления о том, какого цвета должна быть первая строка в группе; группа просто начнется с цветом, противоположным последней строке предыдущей группы. Я хотел, чтобы мои группы всегда начинались с одного цвета ... первый ряд каждой группы всегда должен быть белым, а следующий - цветным.

Основная идея заключалась в том, чтобы сбрасывать переключатель при запуске каждой группы, поэтому я добавил немного кода:

Private bOddRow As Boolean
'*************************************************************************
'-- Display green-bar type color banding in detail rows
'-- Call from BackGroundColor property of all detail row textboxes
'-- Set Toggle True for first item, False for others.
'*************************************************************************
'
Function AlternateColor(ByVal OddColor As String, _
                  ByVal EvenColor As String, ByVal Toggle As Boolean) As String
         If Toggle Then bOddRow = Not bOddRow
         If bOddRow Then 
                Return OddColor
         Else
                 Return EvenColor
         End If
 End Function
 '
 Function RestartColor(ByVal OddColor As String) As String
         bOddRow = True
         Return OddColor
 End Function

Итак, у меня есть три разных типа фона ячеек:

  1. Первый столбец строки данных имеет = Code.AlternateColor ("AliceBlue", "White", True) (это то же самое, что и в предыдущем ответе.)
  2. Остальные столбцы строки данных имеют = Code.AlternateColor ("AliceBlue", "White", False) (Это также то же самое, что и предыдущий ответ.)
  3. Первый столбец группирующей строки имеет = Code.RestartColor ("AliceBlue") (это новинка.)
  4. Остальные столбцы группирующей строки имеют = Code.AlternateColor ("AliceBlue", "White", False) (Это использовалось раньше, но не упоминалось об этом для группировки строки.)

У меня это работает. Если вы хотите, чтобы группирующая строка была неокрашенной или имела другой цвет, из этого должно быть довольно очевидно, как ее изменить.

Не стесняйтесь добавлять комментарии о том, что можно сделать для улучшения этого кода: я новичок как в SSRS, так и в VB, поэтому я сильно подозреваю, что есть много возможностей для улучшения, но основная идея кажется разумной (и она была полезной. для меня) поэтому я хотел выкинуть это здесь.

миша
источник
1

Я пробовал все эти решения в сгруппированном таблисе с пространством строк, и ни одно не помогло во всем отчете. Результатом были повторяющиеся цветные строки, а другие решения привели к чередованию столбцов!

Вот функция, которую я написал, которая работала для меня с использованием счетчика столбцов:

Private bOddRow As Boolean
Private cellCount as Integer

Function AlternateColorByColumnCount(ByVal OddColor As String, ByVal EvenColor As String, ByVal ColCount As Integer) As String

if cellCount = ColCount Then 
bOddRow = Not bOddRow
cellCount = 0
End if 

cellCount  = cellCount  + 1

if bOddRow Then
 Return OddColor
Else
 Return EvenColor
End If

End Function

Для табликса с 7 столбцами я использую это выражение для Row (of Cells) Backcolour:

=Code.AlternateColorByColumnCount("LightGrey","White", 7)
Джереми Томпсон
источник
0

В моих матричных данных отсутствовали значения, поэтому я не смог заставить решение Ахмада работать, но это решение сработало для меня.

Основная идея состоит в том, чтобы создать дочернюю группу и поле в самой внутренней группе, содержащее цвет. Затем установите цвет для каждой ячейки в строке на основе значения этого поля.

Кулак ярости
источник
Проверьте @ Aditya и мой ответ, чтобы обработать недостающие значения в матрице. Полезно, если у вас уже есть (или вы хотите создать поддельную) родительскую группу. Так вам не придется создавать отдельное поле.
рпыж
0

Небольшая модификация других ответов здесь, которая сработала для меня. У моей группы есть два значения для группировки, поэтому я смог просто поместить их оба в первый аргумент с +, чтобы заставить его правильно чередоваться

= Iif ( RunningValue (Fields!description.Value + Fields!name.Value, CountDistinct, Nothing) Mod 2 = 0,"#e6eed5", "Transparent")
Соевый Соус Джонсон
источник
0

При использовании групп строк и столбцов у меня возникла проблема, когда цвета между столбцами чередовались, даже если это была одна и та же строка. Я решил эту проблему, используя глобальную переменную, которая меняется только при изменении строки:

Public Dim BGColor As String = "#ffffff"

Function AlternateColor() As String
  If BGColor = "#cccccc" Then
    BGColor = "#ffffff"
    Return "#cccccc"
  Else
    BGColor = "#cccccc"
    Return "#ffffff"
  End  If
End Function

Теперь в первом столбце строки, которую вы хотите изменить, установите для выражения цвета значение:

= Code.AlternateColor ()

-

В остальных столбцах установите для них все:

= Code.BGColor

Это должно заставить цвета чередоваться только после того, как будет нарисован первый столбец.

Это также может (не поддаётся проверке) улучшить производительность, так как не требуется выполнять математические вычисления для каждого столбца.

Eneerge
источник