If I have a Public Sub at the start of my form code and all my Dim str values there, can I just call them anywhere else on the form code?
Here is how declarations work.
You can declare a variable in a function or subroutine. You can declare a variable in the declarations area (before the first sub or function declaration) of a class or general module. This includes examples of ReDim for arrays. Variable persistence is simple. You need to know WHERE it was created to know its lifetime.
A variable defined in a function or subroutine exists ONLY for as long as the function or subroutine is active, because with one exception, all such variables are declared on the call stack (in something called a Call Frame.) This call frame is the localized keeper of the routine's current execution context - including all "local" variables, the address of the current error handler, the address to which your code returns on routine exit, and some traceback information that you can see using the View >> Call Stack operation from the VBA Window's menu bar. Once you exit a sub or function, its call frame is dissolved and all of its locally declared variables cease to exist. At the next call to that same sub or function, new instances of the variables come into existence on the stack. The one exception is any variable declared as STATIC, which persists and can retain values across multiple activations of the sub/function declaring it.
The question you asked about variables declared in a sub/function is directly answer by the above paragraph. Here are the rest of the rules for variable existence/persistence.
A variable declared in a class module comes into existence when the class object (a form, usually) comes into actual existence, i.e. opens. (The fact that it has POTENTIAL existence doesn't usually matter.) For the duration of its existence, the variable is however you declared it. It ceases to exist if the class object (that supports the class module) closes. If you open the same class object a second time after it was opened and closed, the variables are new instances of themselves and are re-initialized to their default values.
A variable declared in a general module theoretically comes into existence when the app opens and that variable exists until the app closes. It retains any value for the duration of the app UNLESS there is an unhandled error and the only way out of the error is the RESET option. Its scope of PUBLIC or PRIVATE or something else is however you declared it.
Depending on exactly how function/sub variables were defined, it is POSSIBLE for you to recursively activate the routines (i.e. routines CAN call themselves) and thus have more than one active copy of the routine's variables. When that happens, any local variables are local to the currently active instance of the function/sub call and are separate from other instances, each of which has its own call frame. In this case, I believe the STATIC variables are still visible and do NOT get re-initialized in the case of recursion. The one recent time I used that feature, that is the way it appeared to me.
All simple variables declared as noted above lose their value after a RESET operation. However, certain structures such as Dictionaries, TempVars, and user Collections can retain values across a reset. None of them survive an Application.Quit operation.