@ Niara

Yeah, that 100 roll is crazy. It's the kind of ridiculous statline that I'm sure a DM would play around with and gently rib the player for having, spending the odd moment to describe how monsters and pawns alike are "in awe" or maybe even slightly infuriated of how chiseled and perfect the person is looking, whenever it can be fitted in. Maybe even making it a minor theme at some point that Mr Perfect is having a bad hair day and a runny nose.

I actually went back and peaked over the numbers a bit more and there are zero cases of three 18's. 935 rolls had a single 18, 29 had two. Chances of getting a character with actually three 18's and having those be in the right abilities and not ending up with ridiculous strenght values is horrible.

That being said, the chance to get a truly catastrophic roll is somewhat lower since just one roll of 5+ will essentially guarantee somewhat playable stats of at least 7 or more. Not getting a single 5+ with four dice is freaky. But of course it can happen and with strict rules you would be out of luck. You can have your 18 charisma warlock with 16 int and 17 con, but your dex is 3 and your strength is 4. That might be great fun at a table, it could lead to personal quests for a girdle of not being a weakling and maybe some elven gloves of not falling on your backside all the time. But would really anyone play that character in a video game?

However, if we consider the relaxation that Bioware decided on back in the day then it becomes very clear why it was so relatively easy to roll stat monsters in the Baldur's Gate games. If we can trade points between abilities after the roll then all that matters is the sum of dice. 297 out of 10000 rolls had a sum of 87 or more. That's roughly 3%, meaning that at 15 per minute, you'd almost certainly get a very good roll within 5-10 minutes.

Lastly, regarding cooking it up in Excel, it was indeed a bit finicky. I started out with a formula based approach, just put a randbetween(1, 6) in 24 columns, then using sum() of column 1 to 4 minus min() of column 1 to 4. And then 5-8, 9-12, 13-16, and so on. It worked but it was slow. Too many formulas needing calculation and something about formulas just rub me the wrong way. So I gave my lazy bone a swift kicking and wrote a macro instead. It isn't super optimized, but it gets the job done.

Code
Sub RollCharacterStats(Optional ByVal lngRow As Long = 0)
    Dim shOut As Worksheet
    Dim arrDice() As Integer
    Dim i As Integer, j As Integer
    Dim intStat As Integer, intStatSum As Integer, intPointBuySum As Integer
    Dim strDiceRolls As String
    Dim blHas16 As Boolean, blHas18 As Boolean
    
    Set shOut = ThisWorkbook.Sheets("4d6 drop lowest")
    If lngRow = 0 Then lngRow = shOut.Cells(1000000, 1).End(xlUp).Row + 1

    ReDim arrDice(1 To 4)
    intStatSum = 0
    intPointBuySum = 0
    blHas16 = False
    blHas18 = False
    For i = 1 To 6
        For j = 1 To 4
            arrDice(j) = WorksheetFunction.RandBetween(1, 6)
            shOut.Cells(lngRow, 13 + (i - 1) * 4 + j) = arrDice(j)
            strDiceRolls = strDiceRolls & arrDice(j)
        Next j
        intStat = WorksheetFunction.Sum(arrDice(1), arrDice(2), arrDice(3), arrDice(4)) - WorksheetFunction.Min(arrDice(1), arrDice(2), arrDice(3), arrDice(4))
        shOut.Cells(lngRow, i + 1) = intStat
        intStatSum = intStatSum + intStat
        strDiceRolls = strDiceRolls & " "
        If intStat >= 16 Then blHas16 = True
        If intStat >= 18 Then blHas18 = True
    Next i
    shOut.Cells(lngRow, 1) = lngRow - 6
    shOut.Cells(lngRow, 8) = intStatSum
    shOut.Cells(lngRow, 9) = Trim(strDiceRolls)
    shOut.Cells(lngRow, 12) = blHas16
    shOut.Cells(lngRow, 13) = blHas18
End Sub

Sub RollOnce()
    Call RollCharacterStats
End Sub

Sub RollThousands()
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    For i = 1 To 10000
        Call RollCharacterStats
    Next i
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub