1

I need my code to return the randomized string and its returning nothing. Ive included the code to make it easier. I hope this helps.

Everything is running and the msg is coming up but variables dna1 and dna2 are empty.

Dim lengthDNA As Integer

Sub dna()
    Dim str As String, dna1 As String, dna2 As String
    Dim x As Long
    
    lengthDNA = InputBox("Enter the length of DNA sequences (10-250)")
    
    dna1 = RandInteger("ACGT")
    dna2 = RandInteger("ACGT")
    
    MsgBox ("DNA Sequence 1 is: " & dna1 & Chr(13) & "DNA Sequence 2 is: " & dna2), vbInformation
End Sub



Public Function RandInteger(strRandom As String) As String
    dnaBank = Array("A", "C", "G", "T")
    
    For x = 1 To lengthDNA
        Randomize
        strRandom = strRandom & dnaBank(Int((UBound(dnaBank) - LBound(dnaBank) + 1) * Rnd + LBound(dnaBank)))
    Next x
End Function
1
  • You need RandInteger = strRandom before End function or your function never returns a value. Commented May 3, 2022 at 5:35

2 Answers 2

3

Don't use global variables if you don't need to. Declare your variables as local as possible and as close tho their first use as possible. If you need ot submit a variable to another function/sub submit it as parameter.

Choose good names for your variables and functions. RandInteger for example is very confusing. You name your function something with Integer but it returns a String (text). Instead give it a meaningful name eg CreateRandomDNA() and submit the Length you want the DNA to be as parameter.

Option Explicit

Public Sub dna()
    Dim lengthDNA As Long
    
    ' get DNA length from user input, allow user to press cancel
    Dim ReturnValue As Variant
    ReturnValue = Application.InputBox(Prompt:="Enter the length of DNA sequences (10-250)", Type:=1) 'Type:=1 Allow numbers only
    If VarType(ReturnValue) = vbBoolean And ReturnValue = False Then
        'user pressed cancel
        Exit Sub
    Else
        lengthDNA = ReturnValue
    End If
    
    Dim dna1 As String
    dna1 = CreateRandomDNA(lengthDNA)
    
    Dim dna2 As String
    dna2 = CreateRandomDNA(lengthDNA)
    
    MsgBox "DNA Sequence 1 is: " & dna1 & vbCrLf & "DNA Sequence 2 is: " & dna2, vbInformation
End Sub



Public Function CreateRandomDNA(ByVal Length As Long) As String
    Dim dnaBank As Variant
    dnaBank = Array("A", "C", "G", "T")
    
    Randomize
    
    Dim strRandom As String
    Dim x As Long
    For x = 1 To Length
        strRandom = strRandom & dnaBank(Int((UBound(dnaBank) - LBound(dnaBank) + 1) * Rnd + LBound(dnaBank)))
    Next x
    
    CreateRandomDNA = strRandom  ' return random string to function
End Function

If you need to create different strings like DNA, RNA, Amino Acids (for proteins) you can do that in one function too:

Option Explicit

Public Enum BioCodeType
    bctDNA
    bctRNA
    bctAminoAcidSingleLetter
    bctAminoAcidMultiLetter
End Enum

Public Sub dna()
    Dim sequenceLength As Long
    
    Dim ReturnValue As Variant
    ReturnValue = Application.InputBox(Prompt:="Enter the length of DNA sequences (10-250)", Type:=1) 'Type:=1 Allow numbers only
    If VarType(ReturnValue) = vbBoolean And ReturnValue = False Then
        'user pressed cancel
        Exit Sub
    Else
        sequenceLength = ReturnValue
    End If
    
    Dim dna As String
    dna = CreateRandomBioString(sequenceLength, bctDNA)
    
    Dim rna As String
    rna = CreateRandomBioString(sequenceLength, bctRNA)
    
    Dim aminoSingle As String
    aminoSingle = CreateRandomBioString(sequenceLength, bctAminoAcidSingleLetter)
    
    Dim aminoMulti As String
    aminoMulti = CreateRandomBioString(sequenceLength, bctAminoAcidMultiLetter)
    
    MsgBox "DNA Sequence is: " & dna & vbCrLf & _
           "RNA Sequence is: " & rna & vbCrLf & _
           "Amino Acid Sequence (single letter) is: " & aminoSingle & vbCrLf & _
           "Amino Acid Sequence (multi letter) is: " & aminoMulti & vbCrLf _
           , vbInformation
End Sub



Public Function CreateRandomBioString(ByVal Length As Long, ByVal BioCode As BioCodeType) As String
    Dim Bank As Variant
    Dim Seperator As String
    
    Select Case BioCode
        Case bctDNA
            Bank = Array("A", "C", "G", "T")
    
        Case bctRNA
            Bank = Array("A", "C", "G", "U")
            
        Case bctAminoAcidSingleLetter
            Bank = Array("A", "R", "N", "D", "C", "E", "Q", "G", "H", "I", "L", "K", "M", "F", "P", "S", "T", "W", "Y", "V")
    
        Case bctAminoAcidMultiLetter
            Bank = Array("ALA", "ARG", "ASN", "ASP", "CYS", "GLU", "GLN", "GLY", "HIS", "ILE", "LEU", "LYS", "MET", "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL")
            Seperator = "-"
    End Select

    Dim bankSize as Long
    bankSize = UBound(Bank) - LBound(Bank) + 1

    Dim bankMin As Long
    bankMin = LBound(Bank)

    Randomize
    
    Dim strRandom As String
    Dim x As Long
    For x = 1 To Length
        strRandom = strRandom & IIf(strRandom <> vbNullString, Seperator, vbNullString) & Bank(Int(bankSize * Rnd + bankMin))
    Next x
    
    CreateRandomBioString = strRandom
End Function

and it will return something like

enter image description here

Sign up to request clarification or add additional context in comments.

7 Comments

As far as dnaBank is obviously fixed, I would also remove all those UBound & Co. I guess dnaBank(Int(4*Rng)) is enough, isn't it?
@Vitalizzare true, if it is fixed you can do that. If you might want to take this out and expose it as a parameter you would want to keep it. • What you definitely can do is take this calculation Int((UBound(dnaBank) - LBound(dnaBank) + 1) out of the loop, so it is only calculated once and saved in a variable. That will save some calculations at least.
@Pen Yes, right. It's just specifics of this task. By the way, do you know whether it is possible to control rounding rules for parameters?
@Vitalizzare what do you mean by "rounding rules for parameters"?
@Vitalizzare That is because of implicit conversion of a Double or Single value which 3.9 is into a Integer or Long. Because the array dnaBank needs a index that is a positive integer, it casts the decimal into an integer. That is done by the same functions as cInt or cLng and they will round. As you can read in the documentation Type conversion functions where it says "fractions are rounded".
|
2

No return value is ever specified for RandInteger.

Add RandInteger = strRandom as the last statement of the function..

Note

You might also want to check other portions of the code:

  • It does not make much sense to pass a fixed prefix string to the randomizer function. Instead make the target length of the random string a parameter.
  • Randomize initializes VBAs random number generator. It should be called once for the whole program instead of before every call to Rnd as it is now.

1 Comment

I removed randomize underneath the DNA array. That makes so much sense, but im not sure how to pass the length as a parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.