The problem may be as simple as redefining your DECIMAL datatype conversion. Below I do the replace and ISNUMERIC check in one pass then only CAST values that meet that criteria.
--sample data
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
CREATE TABLE #TempTable (
[ID] INT IDENTITY(1,1) NOT NULL,
[Col1] VARCHAR(50) NULL,
PRIMARY KEY (ID))
INSERT INTO #TempTable
SELECT '123456789'
UNION
SELECT '123456789123456789'
UNION
SELECT '123,456,789,123,456,789'
UNION
SELECT NULL
UNION
SELECT ''
UNION
SELECT 'XYZ'
SELECT * FROM #TempTable
If I use DECIMAL(18,2)--the default and what you use in your question--I get the arithmetic overflow error using my sample data above. Change the size of the DECIMAL value and it accepts the larger number without an error.
If you are going to test whether or not the string is numeric you need to do the replacements first. In your original query your WHERE clause is filtering on the original varchar values before you've done the replacements or checked for valid numbers.
SELECT
ID
,CAST(Result AS DECIMAL(20,2)) AS Result
FROM
(
SELECT
ID
,REPLACE(Col1,',','') AS Result
,(CASE
WHEN NULLIF(Col1,'') IS NULL
THEN 0
WHEN ISNUMERIC(ISNULL(NULLIF(REPLACE(Col1,',',''),''),0)) = 1
THEN 1
ELSE 0
END) AS isNum
FROM
#TempTable
) r
WHERE
IsNum = 1