Your questions are pretty broad and cannot really be answered without making a lot of assumptions or giving many alternatives and considerations. From the questions it seems you are looking for rules about what logic goes where. That is generally known as layering. The most common pattern being having three layers: UI; Business (Application) and Data(base). This answer on SO and the links contained within it, will probably help you on your way.
With regard t0 1: The message box should not be displayed by the subs/functions. Message boxes are UI specific implementations and a concern for the UI. The message displayed by the message box can of course come from the subs/functions. If the sub does not return an error message directly but an error code, it is fine to have a separate sub (in the application layer) to return messages based on an error code. This could be part of a separate "localizaion" service when dealing with a multi-lingual UI.
With regard to 2: Depends. They can throw exceptions or they can contain them and return an error code. If you are even remotely considering putting the subs/funcions in a separate module (exe or dll): exceptions should never cross module boundaries. In that case containing exceptions and returning error codes is the way to go.
With regard to 3: The UI can have logic, but that logic should be confined to UI stuff, like enabling and disabling controls. Validation is a business/domain/application concern and the UI should defer to that layer. It should of course have logic, including if statements :-) to process the results of that validation and reflect it in the UI.