Problem Overview
In Siemens SIMATIC WinCC V7.2, a dynamic MsgFilterSQL string assigned to an AlarmControl filters the live (online) message list correctly but returns zero rows when the operator switches the same control to the Short-term archive list or the Long-term archive list. The filter is built in VBScript from user-selected dropdown values and concatenated into a single SQL WHERE clause, for example:
VBScript
Item.MsgFilterSQL = ("CLASS IN (" & Floor_Filter & ") AND PRIORITY IN (" & Priority_Filter & ") AND STATE IN (" & State_Filter & ") AND TEXT1 LIKE '*" & Text_Filter & "*'")
No runtime error is raised. The archive view simply renders an empty result set even when matching messages exist in the archive. This silent failure is the most common cause of "my filter does not work in the archive view" tickets in WinCC V7.x projects, because the AlarmControl does no client-side validation of the SQL string and the SQL Server backend returns zero rows for an unparseable LIKE pattern.
Affected Versions and Components
The behavior has been reproduced and confirmed on the following Siemens SIMATIC WinCC releases:
| Component | Version / Status | Behavior |
|---|---|---|
| SIMATIC WinCC | V7.0 SP2 | Reproduced; same wildcard requirement |
| SIMATIC WinCC | V7.2 (all service packs and updates) | Reproduced; root cause documented in this article |
| SIMATIC WinCC | V7.3 / V7.4 / V7.5 | Same SQL-92 subset, same wildcard expectation |
| AlarmControl (Classic OCX) | Used in graphics, picture windows, and standard alarm screens | All three message sources affected |
| WinCC Runtime Professional (TIA Portal) | V13 through V20 | Same MsgFilterSQL property and same SQL grammar |
The SQL subset and MsgFilterSQL property for TIA Portal WinCC Runtime Professional are documented in the Siemens TIA Portal Help: SQL statements for filtering the alarm view (RT Professional). Although the V7.2 AlarmControl pre-dates the TIA Portal RT Professional implementation, both products share the same SQL grammar for MsgFilterSQL.
CC_WinCC_Alg) apply to the V7.x product family only.
Root Cause
The MsgFilterSQL property of the WinCC AlarmControl is parsed against a fixed SQL-92 subset. In that subset, the multi-character wildcard for the LIKE operator is the percent sign (%), not the asterisk (*). The asterisk is treated as a literal character.
The reason the same string appears to "work" on the live message list is a difference in how each data source is evaluated:
-
Online / live message list — backed by the in-memory ring buffer of the Alarm Logging service. The AlarmControl applies the pattern in-process and tolerates an unparseable
LIKEclause by falling back to a non-restrictive match against the in-memoryMSG_DATAstructures. The user sees what looks like a working filter, but no SQL has actually been issued. - Short-term archive list — served from the configured short-term archive (memory plus flushed segments on disk). Queries go through the same ODBC path used by the long-term archive.
-
Long-term archive list — served from the segmented SQL Server archive database (default name
CC_Alg_<ServerName>_<Timestamp>). Queries are issued as parameterized T-SQL against the archive view.
When the LIKE pattern contains literal asterisks, the SQL engine evaluates it character-by-character against TEXT1. A pattern such as '*Pump*' requires the string to contain actual asterisk characters at positions 1 and 5, which production TEXT1 values never do. The result is an empty set, and the AlarmControl displays "no messages".
How the AlarmControl Consumes MsgFilterSQL
The AlarmControl property sheet exposes a single Selection node that contains both a quick filter (text box at runtime) and a SQL filter. The MsgFilterSQL string is applied on top of any user-entered quick filter. Internally the AlarmControl performs the following steps when the user activates a message source (Online, Short-term, Long-term):
- Resolves the configured data source via the WinCC Message Service (component
CCMsgServ.exe). - Builds a parameterized T-SQL statement using the configured column list (default:
MSGNR, DATETIME, TEXT1..TEXT10, CLASS, TYPE, STATE, PRIORITYand related fields). - Appends the
WHEREclause fromMsgFilterSQLverbatim — no client-side validation is performed. - Executes the query through the ODBC DSN
CC_WinCC_Alg(default name; configurable in WinCC Explorer → "Alarm Logging" → "Archives"). - Maps the result set back to the AlarmControl rows.
Because step 3 does no client-side validation, a malformed SQL string is sent to SQL Server and either rejected by the parser (raising an event-log error) or, more commonly in this scenario, is SQL-compliant but wildcard-mismatched — and executes successfully while returning zero rows. The latter is the case for the * wildcard in a LIKE clause.
Archive List Architecture in WinCC V7.x
WinCC V7.x maintains three distinct message sources for the AlarmControl, each with its own backing store:
| Message source | Backing store | Default configuration path |
|---|---|---|
| Online / live list | In-memory ring buffer of the Alarm Logging service (default 1000 messages, configurable) | WinCC Explorer → "Computer" → "Properties" → "Message Archive" → "Message buffer" |
| Short-term archive list | Memory + flushed segments on local disk (folder <Project>\ArchiveManager\AlarmLogging\ShortTerm) |
WinCC Explorer → "Alarm Logging" → "Archives" → "Short-term archive" |
| Long-term archive list | SQL Server database, segmented by configurable interval (day/week/month) | WinCC Explorer → "Alarm Logging" → "Archives" → "Long-term archive" → "Segments" |
Both archive sources require a working ODBC connection. The default DSN is CC_WinCC_Alg pointing to the WinCC instance \<Server>\WinCC. If this DSN is missing or misconfigured, the AlarmControl will fall back to a no-archive behavior, which can mask the real bug. Always verify the ODBC data source with the SQL Server Management Studio connection test before debugging MsgFilterSQL.
Solution: Use the SQL-92 % Wildcard
Replace every asterisk in the LIKE pattern with a percent sign. The corrected VBScript is:
VBScript
'Declarations
Dim Floor_Filter, Priority_Filter, State_Filter, Text_Filter
Floor_Filter = HmiRuntime.Tags("Floor_Filter").Read
Priority_Filter = HmiRuntime.Tags("Priority_Filter").Read
State_Filter = HmiRuntime.Tags("State_Filter").Read
Text_Filter = HmiRuntime.Tags("Text_Filter").Read
'Filter - use % for LIKE wildcard, never *
Item.MsgFilterSQL = "CLASS IN (" & Floor_Filter & _
") AND PRIORITY IN (" & Priority_Filter & _
") AND STATE IN (" & State_Filter & _
") AND TEXT1 LIKE '%" & Text_Filter & "%'"
The two % characters at the start and end of the LIKE pattern tell the SQL engine to match any prefix and any suffix around the user-entered substring. If the user clears the text filter, Text_Filter will be empty and the resulting pattern '%%' matches every value — which is the expected "no text restriction" behavior.
') and SQL comment markers (--, /*). See the "Field Sanitization" section below for a drop-in helper.
Step-by-Step Correction Procedure
-
Open the WinCC Graphics Designer that hosts the AlarmControl picture (for example
AlarmScreen.Pdl) and select the AlarmControl. - Open the properties dialog → Selection tab. Confirm that the field list is set to the expected columns. The default list covers the standard alarm fields and is required for the columns referenced in the WHERE clause to be selectable.
- Locate the VBScript action that builds the MsgFilterSQL string. In the source project, the action is wired to a button-click or a tag-change event.
-
Replace every
*in a LIKE pattern with%. The condition columns (IN (...)) and equality comparisons are not affected — only LIKE wildcards change. -
Add a trace line at the end of the action:
The trace output will appear in theVBScript HMIRuntime.Trace "Filter=" & Item.MsgFilterSQL & vbNewLineWinCC_aplog.logand in the WinCC Diagnostic window if enabled. If the traced string still contains*, you are looking at the wrong action or the action is being overwritten by a later one. - Recompile and re-download the picture (right-click the AlarmControl → "Configuration dialog" → "OK" to apply). Some projects require a full Graphics Designer restart to clear the cached picture.
- Test in runtime: trigger the filter action, switch the message source dropdown to "Short-term archive" and to "Long-term archive", and confirm that matching rows now appear.
Verifying the Filter via HMIRuntime.Trace
Trace output is the fastest way to confirm both that the correct string is being assigned and that the AlarmControl is forwarding it. Add the following lines around the assignment:
VBScript
Dim sFilter
sFilter = "CLASS IN (" & Floor_Filter & ") AND PRIORITY IN (" & Priority_Filter & _
") AND STATE IN (" & State_Filter & ") AND TEXT1 LIKE '%" & Text_Filter & "%'"
HMIRuntime.Trace ">> MsgFilterSQL before assign: " & sFilter & vbNewLine
Item.MsgFilterSQL = sFilter
HMIRuntime.Trace ">> MsgFilterSQL after assign: " & Item.MsgFilterSQL & vbNewLine
Then enable the WinCC trace:
- Open
WinCC Explorer→ right-click the computer → Properties → Graphics Runtime tab. - Set HMI trace to "On" and Trace level to at least "Errors and warnings".
- Open the Windows application event log (
eventvwr.msc) and filter for sourceWinCC; trace lines appear there as well.
What to look for in the trace:
- If the "before" line still contains
*, your edit is in a different script than the one runtime executes. Search the project for all occurrences ofMsgFilterSQLusing the cross-reference tool in WinCC Explorer. - If the "after" line is empty, the AlarmControl has rejected the string. Re-check the field list (e.g.
TEXT1must be present in the configured column list) and verify that the connection point is the AlarmControl itself rather than a wrapper picture. - If the "after" line is correct and the result is still empty, the issue is downstream (archive ODBC, SQL permissions, segment mismatch). Continue to the "Archive Connection Checklist" section.
MsgFilterSQL Field Reference
The following columns are available in the WHERE clause of MsgFilterSQL for WinCC V7.x. Column names are case-insensitive; the exact set depends on the field list configured in the AlarmControl Selection tab.
| Column | Data type | Typical operator | Notes |
|---|---|---|---|
| MSGNR | Integer |
=, >=, <=, IN
|
Internal alarm number from the message configuration |
| CLASS | Integer |
IN, =
|
Alarm class ID (e.g. 1 = error, 2 = warning) |
| TYPE | Integer | IN |
Alarm type (1 = error, 2 = warning, 3 = message, ...) |
| STATE | Integer | IN |
Bitmask: 1 = came, 2 = went, 3 = ack, 4 = ack gone |
| PRIORITY | Integer | IN |
1..16 typically |
| TEXT1..TEXT10 | String |
LIKE, =
|
User message texts. LIKE wildcards: % (any chars) and _ (single char) |
| DATETIME | DateTime |
>=, <=, BETWEEN
|
Format depends on the configured language |
| AGNR | Integer |
=, IN
|
AS number |
| COMPUTER | String |
=, LIKE
|
Computer name that generated the message |
| USER | String | = |
User that acknowledged the message (after ack) |
| COMMENT | String | LIKE |
Comment added at runtime |
Operators supported in the WHERE clause (per the SQL-92 subset used by the AlarmControl):
- Comparisons:
=,<>,<,<=,>,>= - Logical:
AND,OR,NOT - Set:
IN ( ... ) - Pattern:
LIKEwith%(zero or more chars) and_(single char) - Range:
BETWEEN ... AND ...
Archive Connection Checklist
After the wildcard correction, if the archive list is still empty, walk through the following configuration items in order:
-
ODBC DSN: Open
odbcad32.exeon the WinCC server. Confirm the DSNCC_WinCC_Algexists, points to the SQL Server instance, and the "Test connection" succeeds with the configured WinCC service account. -
SQL permissions: The WinCC runtime user (default
CCSysUser) must havedb_datareaderon theCC_Alg_<ServerName>_<Timestamp>database. Missing SELECT permission on the message view will cause the same silent zero-row behavior. - Segment configuration: In WinCC Explorer → "Alarm Logging" → "Archives" → right-click the archive → "Properties" → "Segments" tab. Confirm at least one segment is enabled and that the path exists on the server. An archive with no segments will return no rows.
- Time range: The AlarmControl's "Time range" setting in the Selection tab can be set to "All", "Last hour", "Today", "Custom". A "Today" filter applied to an archive that holds yesterday's segments will return zero rows.
-
Server vs client: On multi-server projects, the AlarmControl must be configured with the correct server prefix. Use the
\<ServerName>::syntax in the Server prefix field if mixing server-side and client-side alarm sources. -
WinCC service state: Both
CCAlgLogServerandCCMsgServmust be in "Started" state. The AlarmControl queries fail silently if either is stopped.
Field Sanitization for Free-Text Inputs
The user's project reads dropdown values, which are trusted, but the pattern below shows how to harden the LIKE input if free text is added later:
VBScript
Function SafeLike(sIn)
Dim s
s = Replace(sIn, "'", "''") ' escape single quote (T-SQL)
s = Replace(s, "--", "") ' remove SQL comment marker
s = Replace(s, "/*", "") ' remove block comment start
s = Replace(s, "*/", "") ' remove block comment end
SafeLike = s
End Function
Text_Filter = SafeLike(HmiRuntime.Tags("Text_Filter").Read)
Item.MsgFilterSQL = "TEXT1 LIKE '%" & Text_Filter & "%'"
Note that the percent sign in the surrounding pattern is fixed in the script — do not allow the user to inject % or _ into Text_Filter, otherwise any pattern can be matched and the filter loses its purpose.
Advanced Filter Examples
The corrected syntax scales to more complex conditions. The following examples are confirmed to work on the WinCC V7.x AlarmControl:
VBScript
' Date range filter using BETWEEN
Item.MsgFilterSQL = "DATETIME BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59' AND CLASS IN (1,2)"
' Multiple text columns with OR
Item.MsgFilterSQL = "(TEXT1 LIKE '%Pump%' OR TEXT2 LIKE '%Pump%') AND STATE IN (1,2)"
' Negation with NOT
Item.MsgFilterSQL = "CLASS IN (1,2) AND TEXT1 NOT LIKE '%Maintenance%'"
' Single-character wildcard with _
Item.MsgFilterSQL = "TEXT1 LIKE 'Error_01'"
' Priority range with BETWEEN
Item.MsgFilterSQL = "PRIORITY BETWEEN 1 AND 5 AND STATE = 1"
Compatibility Note: WinCC V6.x, V7.0 SP2, and V7.5
The % wildcard requirement is documented in the WinCC V7.0 SP2 help and has not changed through V7.5. Projects that were upgraded from WinCC V6.x, which used the older VBScript native Like operator with * and ?, will retain the V6-style wildcards in VBScript Like comparisons but must use % and _ in MsgFilterSQL. The two operators are independent:
| Context | Wildcard: any chars | Wildcard: single char |
|---|---|---|
VBScript native Like operator |
* |
? |
| MsgFilterSQL SQL dialect | % |
_ |
When the source code is ported between the two contexts, the wildcards must be translated. This is the most common upgrade-time regression that produces the exact symptom in this article.
Verification Matrix
| Check | Expected | Pass criterion |
|---|---|---|
MsgFilterSQL trace contains %
|
Pattern uses % not *
|
No * in LIKE clauses |
| Online message list filter | Filter applies to live messages | Row count matches unfiltered list minus non-matching rows |
| Short-term archive list filter | Filter applies to short-term archive | Row count matches for the configured time range |
| Long-term archive list filter | Filter applies to long-term archive | Row count matches for the configured time range and segments |
ODBC test (DSN CC_WinCC_Alg) |
Connection succeeds | "Test completed successfully" from odbcad32 |
| SQL Server view access | WinCC user has SELECT on archive view | Manual SELECT TOP 10 returns rows in SSMS |
| Time range in Selection tab | "All" or matches expected window | No accidental "Today" on yesterday's archive |
| AlarmControl message source | Online / Short-term / Long-term toggleable | Toolbar dropdown reflects active source |
Frequently Asked Questions
Why does the filter work on the live list but not the archive list?
The AlarmControl uses an in-memory ring buffer for the live list and tolerates an unparseable MsgFilterSQL by returning rows without applying the LIKE pattern. The short-term and long-term archive lists forward the same string to the SQL Server archive database; the SQL dialect that MsgFilterSQL uses requires % instead of * for LIKE wildcards, so the asterisks are treated as literal characters and the query returns zero rows.
What is the correct wildcard for MsgFilterSQL LIKE clauses?
Use % for any number of characters and _ for a single character, per SQL-92. Example: TEXT1 LIKE '%Pump%' matches any TEXT1 value containing "Pump". The asterisk * is not recognized as a wildcard in the MsgFilterSQL parser.
Does the same wildcard rule apply to TIA Portal WinCC Runtime Professional?
Yes. The TIA Portal RT Professional Alarm View uses the same MsgFilterSQL property and the same SQL-92 subset. The reference is documented in the TIA Portal Help at SQL statements for filtering the alarm view (RT Professional).
Can MsgFilterSQL use a date range?
Yes. Use the BETWEEN operator with a format the SQL Server regional settings can parse, e.g. DATETIME BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59'. Adjust the format string to match the language settings of the WinCC server.
How do I confirm the AlarmControl is forwarding the filter to the archive?
Enable HMIRuntime.Trace on the line that assigns MsgFilterSQL, set the WinCC trace level to "Errors and warnings" or higher, and inspect the Windows application event log filtered for source WinCC. The trace line will show the exact string handed to the AlarmControl. If the string is correct and the result is still empty, the ODBC connection or SQL permissions are the next items to verify.