To solve this problem, we need to define the decision variables, objective function, and constraints. Let's break down the problem step by step.

1. **Decision Variables**: We have two decision variables - the amount invested in Bob's farm (let's call it `x`) and the amount invested in Joe's farm (let's call it `y`).

2. **Objective Function**: The objective is to maximize earnings from both farms. Given that investments in Bob's farm earn 8% and those in Joe's farm earn 6%, we can express the total earnings as `0.08x + 0.06y`. We aim to maximize this function.

3. **Constraints**:
   - The total amount invested cannot exceed $50,000: `x + y <= 50000`.
   - The amount invested in Bob's farm must be at least three times the amount invested in Joe's farm: `x >= 3y`.
   - The amount invested in Bob's farm can be at most $40,000: `x <= 40000`.
   - Non-negativity constraints since we cannot invest a negative amount: `x >= 0` and `y >= 0`.

Now, let's translate these into Gurobi code:

```python
from gurobipy import *

# Create a new model
m = Model("Investment_Optimization")

# Define the decision variables
x = m.addVar(lb=0, name="Bob's_Farm")  # Amount invested in Bob's farm
y = m.addVar(lb=0, name="Joe's_Farm")  # Amount invested in Joe's farm

# Define the objective function: Maximize earnings
m.setObjective(0.08*x + 0.06*y, GRB.MAXIMIZE)

# Define the constraints
m.addConstr(x + y <= 50000, "Total_Investment")
m.addConstr(x >= 3*y, "Bob_vs_Joe")
m.addConstr(x <= 40000, "Max_Bob")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution found: Invest ${x.x:.2f} in Bob's farm and ${y.x:.2f} in Joe's farm.")
else:
    print("No optimal solution found. The problem might be infeasible.")

# Print the objective function value
print(f"Maximum earnings: {m.objVal:.2f}")
```