Classifying the aspect ratio of the screen dimensions In my project, I have three different userforms to display, optimized for three different aspect ratios. I need my code to call the screen resolution of the user's monitor, then check to see which category it belongs to, and finally choose the appropriate userform.

I've gotten as far as categorizing, but I'm self-taught and have been using absolutely horrendous code. I've just taken every aspect ratio available on our machines and put it into an if  then statement; when the correct if statement is triggered, it populates the variable Asp.

I'm absolutely certain there's a better way to do this. I would like to;


find a mathematical way to represent a "range" of ratios, as not every resolution in the 16:9 category, for example, is exactly 16/9, and 
clean up the validation system that picks the right category for the user's setup. Possibly an array or a Case statement?




Declare Function getsystemmetrics32 Lib "User32" _
    Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long

Sub callAspectRatio()

Dim w As Long
Dim h As Long
Dim Asp As String

w = getsystemmetrics32(0)
h = getsystemmetrics32(1)

If w = 1920 And h = 1080 Then Asp = "16:9"
If w = 1680 And h = 1050 Then Asp = "16:9"
If w = 1600 And h = 900 Then Asp = "16:9"
If w = 1366 And h = 768 Then Asp = "16:9"
If w = 1360 And h = 768 Then Asp = "16:9"
If w = 1280 And h = 720 Then Asp = "16:9"
If w = 1280 And h = 600 Then Asp = "16:9"

If w = 1440 And h = 900 Then Asp = "8:5"
If w = 1280 And h = 1024 Then Asp = "8:5"
If w = 1280 And h = 960 Then Asp = "8:5"

If w = 1600 And h = 1200 Then Asp = "4:3"
If w = 1400 And h = 1050 Then Asp = "4:3"
If w = 1280 And h = 1024 Then Asp = "4:3"
If w = 1280 And h = 960 Then Asp = "4:3"
If w = 1152 And h = 864 Then Asp = "4:3"
If w = 1024 And h = 768 Then Asp = "4:3"
If w = 800 And h = 600 Then Asp = "4:3"

MsgBox Asp

End Sub
The firs thing worth pointing out is that you are ignoring a lot of special meaning with your current approach. Aspect ratios are a function determined by Width : Height and thus we can use an aspect ratio and an inputted Width and Height to get the aspect we want, instead of looking through a list that are just saying the same thing in different ways.

I took your original code and calculated each aspect ratio in order. Here are the results:

'    1.77777777777778 16:9
'    1.6 16:9
'    1.77777777777778 16:9
'    1.77864583333333 16:9
'    1.77083333333333 16:9
'    1.77777777777778 16:9
'    2.13333333333333 16:9
'    1.6 8:5
'    1.25 8:5
'    1.33333333333333 8:5
'    1.33333333333333 4:3
'    1.33333333333333 4:3
'    1.25 4:3
'    1.33333333333333 4:3
'    1.33333333333333 4:3
'    1.33333333333333 4:3
'    1.33333333333333 4:3


A reduced list would look like this:

'1.77... ' 16:9
'1.6     ' 16:9
'1.778   ' 16:9
'2.133   ' 16:9
'1.6     ' 8:5
'1.25    ' 8:5
'1.33... ' 8:5
'1.33... ' 4:3
'1.25    ' 4:3


Aside from the couple of instances of a single ratio being matched to two different aspects, they are fairly consistent. So then I checked each of the original aspects and their results:

?16/9
 1.77777777777778 
?8/5
 1.6 
?4/3
 1.33333333333333


In turn, we have a very simple function to get an aspect ratio from a width and height:

Public Function GetAspectRatio(ByVal Width As Long, ByVal Height As Long) As String
    Select Case Round(Width/ Height, 3)
    Case Is &lt;= 1.33
        GetAspectRatio = "4:3"
    Case Is &lt;= 1.6
        GetAspectRatio = "8:5"
    Case Is &gt; 1.6
        GetAspectRatio = "16:9"
    Case Else
        ' Error : Ratio not pre-defined.
    End Select
End Function


Then your original code becomes this:

Declare Function GetSystemMetrics32 Lib "User32" _
    Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long

Sub DisplayAspectRatio()
    Dim Width As Long
    Width = GetSystemMetrics32(0)

    Dim Height As Long
    Height = GetSystemMetrics32(1)

    MsgBox "Your aspect ratio is : " &amp; GetAspectRatio(Width, Height)
End Sub


We could improve this a bit further by employing the use of constant values and such, but overall this will point you in the right direction.

Note that, with the improved code, I made sure to use clear variable names. Most users will understand what h means in context, but Height is clear to any user. Even better would be WindowHeight so that, even if your reader was completely dumb to reading code, they would know what that variable was. Same goes for naming Functions, and Subroutines.

Best of luck!