#DEFINE SQL_FETCH_NEXT 1 #DEFINE SQL_FETCH_FIRST 2 #DEFINE SQL_SUCCESS 0 #DEFINE MAX_STRING 128 LOCAL j WAIT WINDOW "Loading Data Sources..." NOWAIT DECLARE INTEGER SQLDataSources IN ODBC32.DLL ; INTEGER henv, SHORT fdirection, ; STRING @szDSN, INTEGER cbDSNMax, ; INTEGER @pcbDSN, STRING @szDescription, ; INTEGER cbDescriptionMax, INTEGER @pcbDescriptionn hEnv = VAL(SYS(3053)) && The hEnv (converted to a number) cbDsnMax = MAX_STRING && How long can the DSN Name be? pcbDSN = 0 && How many were actually returned cbDescriptionMax = MAX_STRING && How long can the description be? pcbDescriptionn = 0 && How long the description actually was fDirection = SQL_FETCH_FIRST && The first time start at the top retVal = SQL_SUCCESS && Start with no errors j = 1 DO WHILE (retVal = SQL_SUCCESS) szDsn = SPACE(MAX_STRING+1) && Make sure there is enough space szDescription = SPACE(MAX_STRING+1) retval = SQLDataSources(hEnv, fDirection, ; @szDSN, cbDSNMax, @pcbDSN, ; @szDescription, cbDescriptionMax, @pcbDescriptionn) retval = IIF(EMPTY(LEFT(szDSN, pcbDSN)), -1, SQL_SUCCESS) *-- add to the array if the data source matches IF retval = SQL_SUCCESS AND ; ALLTRIM(UPPER(this.cDataSourceFilter)) $ ; UPPER(ALLTRIM(LEFT(szDescription, pcbDescriptionn))) DIMENSION this.aSQLDataSources[j, 2] this.aSQLDataSources[j, 1] = LEFT(szDSN, pcbDSN) this.aSQLDataSources[j, 2] = LEFT(szDescription, pcbDescriptionn) j = j + 1 ENDIF * We only want to do the SQL_FETCH_FIRST the first time fDirection = SQL_FETCH_NEXT ENDDO WAIT CLEAR RETURN IIF(TYPE("this.aSQLDataSources[1, 1]") = "C", .t., .f.)Note that I filter on a property called this.cDataSourceFilter. This is set to "SQL Server" so that only SQL Server ODBC data sources will show up in the combo box.