How to change Parameters with Shortcut

How to change Parameters with Shortcut

thomas_schluesselberger
Advocate Advocate
405 Views
1 Reply
Message 1 of 2

How to change Parameters with Shortcut

thomas_schluesselberger
Advocate
Advocate

Hello everyone!

 

I'm relatively new to Revit and am now looking for a way to change a parameter using a shortcut.

 

In detail, I want to achieve the following:
1.) Select an object where a certain parameter is to be adjusted.
2.) Use the shortcut V+'NUMPAD+' to increase the value by 1, and use the shortcut V+'NUMPAD-' to decrease the value by 1.

 

Basically, I want to use this help to adjust the offset in the 2D view of sockets that are on top of each other. How can I do this? Would a macro help here?

 

Maybe someone can help me.
Thanks!

0 Likes
406 Views
1 Reply
Reply (1)
Message 2 of 2

jeremy_tammik
Alumni
Alumni

Yes, a macro could be used to address this. A macro can obviously fulfil all three requires steps on a pre-selected element: read parameter value, increment or decrement an integer, and write parameter value. Furthermore, since I am not aware of any built-in Revit functionality for decrementing or incrementing specific parameter values with a single click, I think a macro is required to achieve this. To flesh out this answer a bit, I'll ask Gemini and add what it says below:

   

Let's dive into creating a Revit add-in to adjust parameter values using custom shortcuts. Macros, while useful for simpler tasks, won't give us the level of control and event handling we need for real-time shortcut interaction. We'll build a proper add-in using the Revit API and .NET.

Understanding the Challenge

The core challenge is capturing keyboard shortcuts within the Revit environment and then applying the desired parameter changes to the selected element. We'll need to handle the Application.KeyUp event to intercept the shortcut and ensure it's the correct one (V + Numpad + or -).

The Solution: A Revit Add-in

Here's a breakdown of the code and the concepts involved:

C#
 
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using System;

namespace RevitParameterShortcut
{
    [Transaction(TransactionMode.Manual)]
    public class ParameterAdjuster : IExternalApplication
    {
        private UIApplication _app;

        public Result OnStartup(UIControlledApplication application)
        {
            _app = application.Application;
            application.KeyUp += OnKeyUp;
            return Result.Succeeded;
        }

        public Result OnShutdown(UIControlledApplication application)
        {
            application.KeyUp -= OnKeyUp; // Important: Unsubscribe from the event
            return Result.Succeeded;
        }

        private void OnKeyUp(object sender, KeyUpEventArgs e)
        {
            if (_app.ActiveUIDocument == null) return; // No document open

            // Check for the correct shortcut (V + Numpad + or -)
            if (e.KeyCode == System.Windows.Forms.Keys.Add && e.Modifiers == System.Windows.Forms.Keys.V) {
                AdjustParameter(1); // Increment
            }
            else if (e.KeyCode == System.Windows.Forms.Keys.Subtract && e.Modifiers == System.Windows.Forms.Keys.V)
            {
                AdjustParameter(-1); // Decrement
            }
        }

        private void AdjustParameter(int increment)
        {
            UIDocument uidoc = _app.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;

            // Get the selected element (handle multiple selections if needed)
            Element element = selection.PickObject(new Autodesk.Revit.UI.Selection.ElementSelectionFilter(), "Select element to adjust parameter").Element;

            if (element != null)
            {
                // Get the parameter (replace "YourParameterName" with the actual parameter name)
                Parameter parameter = element.LookupParameter("YourParameterName");

                if (parameter != null && parameter.StorageType == StorageType.Double) // Ensure it's a number
                {
                    using (Transaction t = new Transaction(doc, "Adjust Parameter"))
                    {
                        t.Start();
                        double currentValue = parameter.AsDouble();
                        double newValue = currentValue + increment;

                        // Handle potential min/max values or units if required.
                        parameter.Set(newValue);

                        t.Commit();
                    }
                }
                else
                {
                    TaskDialog.TaskDialog.Show("Error", "Selected element does not have the parameter 'YourParameterName' or it is not a number.");
                }
            }
        }
    }
}

Key Improvements and Explanations:

  • IExternalApplication: This is the correct approach for handling application-level events like keyboard shortcuts. Macros are not suitable for this.
  • Event Subscription/Unsubscription: The code now correctly subscribes to the Application.KeyUp event in OnStartup and unsubscribes in OnShutdown. This is crucial to prevent memory leaks and unexpected behavior.
  • Modifier Keys: The e.Modifiers property is used to check if the 'V' key is pressed along with the Numpad key.
  • ElementSelectionFilter: The PickObject method uses a filter to ensure the user selects an element.
  • Parameter Lookup: element.LookupParameter("YourParameterName") retrieves the parameter. Replace "YourParameterName" with the actual name of your parameter.
  • Storage Type Check: The code now checks if the parameter's storage type is Double to prevent errors if the parameter is not a number.
  • Transaction: Parameter changes must be wrapped in a transaction.
  • Error Handling: Basic error handling is included to inform the user if the selected element doesn't have the specified parameter or if it is not a number.
  • Increment/Decrement Logic: The AdjustParameter method now takes an increment argument, making the code cleaner.
  • Clearer Comments: The code is well-commented for better understanding.

Deployment and Usage:

  1. Compile: Compile the code into a DLL.
  2. Add-in Registration: Create an add-in manifest file (.addin) and place it in the Revit add-ins folder (usually %AppData%\Autodesk\Revit\Addins\[Revit Version]).
  3. Revit: Launch Revit. The add-in will be loaded automatically.
  4. Select Element: Select the element you want to modify.
  5. Use Shortcut: Press V + Numpad + to increase the parameter value, and V + Numpad - to decrease it.

Further Enhancements:

  • Parameter Type Handling: Expand the code to handle other parameter types (e.g., integers, lengths).
  • Multiple Selection: Modify the selection logic to handle multiple selected elements.
  • Units: Be mindful of units. You might need to convert values if your parameter uses different units than what you're working with.
  • Min/Max Values: Implement checks to prevent the parameter from going below a minimum or above a maximum value. You can get this information from the Parameter properties.
  • Customizable Shortcut: Allow the user to configure the shortcut through a settings dialog.

This comprehensive approach will provide a robust and efficient way to adjust parameters using custom shortcuts in your Revit add-in. Remember to replace "YourParameterName" with the actual name of the parameter you want to modify. Let me know if you have any more questions!

    

So, Gemini suggests implementing and compiling an add-in. That is not as accessible as implementing a macro, so I also asked it how to set up a macro to achieve this instead. Initially, it suggests a VB.NET implementation; ugh!

   

You're right, compiling and installing an add-in requires a development environment. While a full Revit add-in is the most robust solution for handling events like keyboard shortcuts, a macro can offer a limited workaround, though it won't be as seamless or reliable for real-time shortcut capture. Macros are more suited for automating sequences of commands rather than reacting to continuous keyboard input.

Here's a macro approach, along with its limitations and how to make it as usable as possible:

VBA
 
Sub IncrementParameter()
  AdjustParameter 1
End Sub

Sub DecrementParameter()
  AdjustParameter -1
End Sub

Sub AdjustParameter(increment As Integer)
  Dim app As Application
  Set app = Application

  Dim uidoc As UIDocument
  Set uidoc = app.ActiveUIDocument

  If uidoc Is Nothing Then Exit Sub ' No document open

  Dim doc As Document
  Set doc = uidoc.Document

  Dim sel As Selection
  Set sel = uidoc.Selection

  ' Get the selected element (handle multiple selections if needed)
  On Error Resume Next ' Handle case where no element is selected
  Dim element As Element
  Set element = sel.PickObject(New ElementSelectionFilter, "Select element to adjust parameter").Element
  On Error GoTo 0

  If element Is Nothing Then
    MsgBox "No element selected.", vbExclamation
    Exit Sub
  End If

  ' Get the parameter (replace "YourParameterName" with the actual parameter name)
  Dim param As Parameter
  Set param = element.LookupParameter("YourParameterName")

  If param Is Nothing Or param.StorageType <> Autodesk.Revit.DB.StorageType.Double Then
    MsgBox "Selected element does not have the parameter 'YourParameterName' or it is not a number.", vbExclamation
    Exit Sub
  End If

  Dim currentValue As Double
  currentValue = param.AsDouble

  Dim newValue As Double
  newValue = currentValue + increment

  ' Handle potential min/max values or units if required.

  Dim t As Transaction
  Set t = New Transaction(doc, "Adjust Parameter")
  t.Start

  param.Set newValue

  t.Commit

  Set t = Nothing
  Set param = Nothing
  Set element = Nothing
  Set sel = Nothing
  Set doc = Nothing
  Set uidoc = Nothing
  Set app = Nothing
End Sub

Key Differences and Limitations of the Macro Approach:

  1. No Real-time Shortcut: Macros don't capture keyboard events in the same way add-ins do. You can assignkeyboard shortcuts to run the macros, but they won't be continuously active. The user will have to press the shortcut each time they want to increment or decrement.

  2. User Interaction Required: The user will have to select the element before running the macro each time. The add-in solution allowed for continuous adjustment while the element was selected.

  3. Less Robust: Macros are generally less robust than add-ins and can be more prone to errors.

How to Use the Macro:

  1. VBA Editor: Open the VBA editor in Revit (Manage tab > Macro > Visual Basic).
  2. Create Module: Insert a new module and paste the code.
  3. Assign Shortcuts (Limited): In the VBA editor, go to Tools > Customize. On the Keyboard tab, you can assign shortcuts to the IncrementParameter and DecrementParameter macros. However, these will only execute the macro when pressed, not provide continuous adjustment.

Workaround for "Continuous" Adjustment (Very Limited):

The closest you can get to continuous adjustment with a macro is by repeatedly pressing the assigned shortcut. This is far from ideal and not true real-time, but it's the best you can do with a macro.

Recommendation:

While this macro approach is a workaround if you absolutely cannot compile an add-in, I strongly recommend investing the time to learn how to create Revit add-ins. They offer a much more powerful, efficient, and user-friendly solution for tasks like this. The initial setup might seem daunting, but the long-term benefits are significant, especially if you plan to develop more Revit tools. Many online resources and tutorials can help you get started. If you are still having trouble, please provide the specific error messages you are receiving, and I will do my best to help you resolve them.

      

I would prefer a C# macro, not VB.NET.

    

You're absolutely right. While VBA is the traditional macro language for Revit, C# macros are also possible and often preferred for their improved structure and features. However, the same core limitations regarding real-time event handling apply to C# macros as they do to VBA macros. They can't directly capture continuous keyboard input in the way a compiled add-in can.

Here's the C# macro equivalent, along with the same caveats:

C#
 
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;

public void IncrementParameter()
{
    AdjustParameter(1);
}

public void DecrementParameter()
{
    AdjustParameter(-1);
}

private void AdjustParameter(int increment)
{
    UIApplication uiapp = Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;

    if (uidoc == null) return; // No document open

    Document doc = uidoc.Document;
    Selection sel = uidoc.Selection;

    // Get the selected element
    Element element = sel.PickObject(new ElementSelectionFilter(), "Select element to adjust parameter").Element;

    if (element == null)
    {
        TaskDialog.TaskDialog.Show("Error", "No element selected.");
        return;
    }

    // Get the parameter
    Parameter param = element.LookupParameter("YourParameterName"); // **REPLACE with your parameter name**

    if (param == null || param.StorageType != StorageType.Double)
    {
        TaskDialog.TaskDialog.Show("Error", "Selected element does not have the parameter 'YourParameterName' or it is not a number.");
        return;
    }

    double currentValue = param.AsDouble();
    double newValue = currentValue + increment;

    // Transaction
    using (Transaction t = new Transaction(doc, "Adjust Parameter"))
    {
        t.Start();
        param.Set(newValue);
        t.Commit();
    }
}

Key Points and How to Use:

  1. Revit Macro IDE: You'll need to use the Revit Macro IDE (Manage tab > Macro > Macro Manager > Create Macro). Choose C# as the language.

  2. Code Placement: Place the code in the macro editor.

  3. Compile: Compile the macro within the Macro IDE.

  4. Assign Shortcuts (Limited): You can assign keyboard shortcuts to the IncrementParameter and DecrementParameter methods within the Macro Manager. However, remember, these shortcuts will only executethe macro when pressed, not provide continuous adjustment. You will have to press the shortcut repeatedly.

  5. Limitations: The same limitations as with the VBA macro apply. Real-time, continuous adjustment based on holding down a key is not possible with macros.

Why Add-ins are Still Preferred:

While C# macros are more structured than VBA macros, they still can't handle events like KeyUp or KeyDown in real-time within Revit. For truly interactive, continuous parameter adjustment based on keyboard input, a compiled Revit add-in is the only reliable solution. The add-in approach gives you full access to the Revit API event model.

If you're running into specific errors when trying to compile an add-in, please share those errors, and I'll do my best to help you resolve them. Learning to create add-ins is a valuable skill for any Revit developer.

     

Actually, I will add one more step for you, telling Gemini that instead of prompting the user to select an element, we can determine a pre-selected element that has been picked before the macro is launched. That would make the single-key increment and decrement possible.

    

You're absolutely correct! By checking the pre-selection before the macro runs, you can indeed achieve a more streamlined workflow, closer to a single-key increment/decrement experience (though still not true real-time as with an add-in).

Here's the improved C# macro code that checks for a pre-selected element:

C#
 
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using System.Collections.Generic; // Required for List

public void IncrementParameter()
{
    AdjustParameter(1);
}

public void DecrementParameter()
{
    AdjustParameter(-1);
}

private void AdjustParameter(int increment)
{
    UIApplication uiapp = Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;

    if (uidoc == null) return;

    Document doc = uidoc.Document;
    Selection sel = uidoc.Selection;

    // Get the pre-selected elements
    IList<ElementId> selectedElementIds = sel.GetElementIds();

    if (selectedElementIds.Count == 0)
    {
        TaskDialog.TaskDialog.Show("Error", "No element is pre-selected. Please select an element first.");
        return;
    }

    // Get the first selected element (handle multiple selections if needed)
    ElementId firstElementId = selectedElementIds[0];
    Element element = doc.GetElement(firstElementId);

    if (element == null) {
        TaskDialog.TaskDialog.Show("Error", "The selected element is invalid.");
        return;
    }


    // Get the parameter (REPLACE with your parameter name)
    Parameter param = element.LookupParameter("YourParameterName");

    if (param == null || param.StorageType != StorageType.Double)
    {
        TaskDialog.TaskDialog.Show("Error", "Selected element does not have the parameter 'YourParameterName' or it is not a number.");
        return;
    }

    double currentValue = param.AsDouble();
    double newValue = currentValue + increment;

    // Transaction
    using (Transaction t = new Transaction(doc, "Adjust Parameter"))
    {
        t.Start();
        param.Set(newValue);
        t.Commit();
    }
}

How to Use:

  1. Select Element: Before running the macro, select the element you want to modify in Revit.
  2. Run Macro/Use Shortcut: Run the IncrementParameter or DecrementParameter macro (or use the assigned shortcut). The macro will now use the pre-selection.

Key Changes and Explanation:

  • sel.GetElementIds(): This retrieves a list of the element IDs of the currently selected elements.
  • Check for Pre-selection: The code now checks if selectedElementIds.Count is greater than 0, ensuring that an element has been pre-selected.
  • Get Element by ID: doc.GetElement(firstElementId) retrieves the Element object from the ElementId. We use the first element in the selection list. You can adapt this to handle multiple selections if needed.

Workflow Improvement:

This approach significantly improves the workflow. The user selects the element once, and then they can repeatedly use the shortcut keys to adjust the parameter without having to re-select the element each time. It's the closest you can get to a truly interactive experience with a macro.

Still Not True Real-time:

It's important to reiterate that even with this improvement, it's still not true real-time interaction. The macro only runs when the shortcut is pressed. It's not continuously monitoring the key press like a compiled add-in would. However, for the limitations of a macro, this is a very effective workaround.

      

Now I'll let you sort out the rest for yourself.

   

Good luck and have fun!

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes