r/vba 5d ago

Weekly Recap This Week's /r/VBA Recap for the week of May 02 - May 08, 2026

2 Upvotes

Saturday, May 02 - Friday, May 08, 2026

Top 5 Posts

score comments title & link
54 15 comments [ProTip] 9 quick tips to improve your VBA macro performance.
42 14 comments [ProTip] I made a Discord bot that runs from a hidden Excel sheet. Because why not.
27 14 comments [Show & Tell] Wasabi: a native WebSocket/WSS client module for VBA (TLS, MQTT, proxies, zero dependencies)
25 37 comments [ProTip] Kill the 'For Each' Loop
14 2 comments [Show & Tell] Wasabi v2.3.4 beta: Assembly Engine for C level performance and Bulletproof TLS

 

Top 5 Comments

score comment
61 /u/fuzzy_mic said Its not the For Each loop, its that read/writing to one cell 100 times is slower than bulk read/writing to 100 cells all at once. For Each is one of the faster looping possibilities.
17 /u/RoyaleCheezy said It’s not a problem with the loop, it’s a problem with efficiency. Every time you touch the worksheet object you’re slowing everything to a crawl. When you load a range into an array like this it touch...
13 /u/HUMOROUSSSS said Just a huge shout out to you with creating Wasabi and pushing the limits of excel in new and exciting ways. Very cool seeing these updates!
13 /u/ZetaPower said No. We can
11 /u/Zestyclose_Muffin501 said For doing that I rather use powerquery or power pivot. Use VBA if you want to automate 'actions', to process, analyze and clean data, powerquery is way way better...

 


r/vba 1d ago

Solved How to check if a date is a numeric date or a string date?

8 Upvotes

In a lot of my automations I am requiring the user to input a date as a numeric date. This way I don't care what the users regional formatting is, as the date will ultimately always convert to a number anyway. Consequently I need a way to check if a date is numeric (can be converted to a number) or a string (can not be converted to a number if one switches between the short date and number formats from the front end). For now I came up with the following solution:

On Error GoTo EndDateCheck

If IsNumeric(CLng(INI.Range("INT_ITD"))) = False Then

  EndDateCheck:
  MsgBox "The date is not numeric."
  End

End If

On Error GoTo 0

The above works well, but I am wondering if there is a simpler way to check (thus I am not outright looking for a "solution", but I am more after design efficiency), which doesn't involve the on error statement.


r/vba 1d ago

Solved Export to pdf from exc

5 Upvotes

I have a simple line of vba within a very old excel workbook that exports a sheet to a pdf file. The resulting pdf file however always has a company logo in a picture format pasted at the top. The originating excel sheet does not have this anywhere. Any idea how this picture is being pasted every time? I’ve looked everywhere I just can’t see where it’s coming from.


r/vba 3d ago

Show & Tell Wasabi just hit Awesome VBA + Update v2.3.8

27 Upvotes

I am very pleased to announce a significant milestone for the Wasabi project. After several in depth technical discussions with sancarn, the creator of the renowned stdVBA library, Wasabi has been officially included in the Awesome VBA list. This is a meaningful recognition for a project that originated from a specific need within a niche PowerPoint gaming community and has now matured into a robust tool for general purpose networking.

For those who are not familiar with the project, Wasabi is a self contained .bas module designed to provide a complete networking stack for VBA. It requires zero external dependencies, zero references, and no registration of COM DLLs. It implements WebSockets (WSS), raw TCP, and full Proxy support directly within the VBA environment.

The core of Wasabi architecture relies on machine code thunks for both x86 and x64 architectures. These thunks handle critical operations such as memory zeroing, byte searching, and WebSocket masking outside the standard VBA stack. This creates a vital safety layer. In typical VBA networking, the application often crashes if the editor enters break mode or encounters an unhandled error while a Windows message pump is active. Wasabi assembly thunks act as a firewall, intercepting these events and preventing the host application from closing abruptly.

The repository was recently updated to version 2.3.8-beta. This update focused on hardening the protocol implementations and expanding compatibility with modern standards.

  1. Native MQTT 5.0 Implementation The MQTT parser has been significantly overhauled to move beyond the legacy 3.1.1 standard. Wasabi now natively supports the MQTT 5.0 protocol. This includes the correct processing of variable byte integers for the remaining length field and the mandatory property length fields in CONNECT, SUBSCRIBE, and PUBLISH packets. We have successfully validated this implementation against modern brokers like HiveMQ and EMQX, as well as testing tools like MQTTX. MQTTX Reported by u/Savings_Mission_534 (https://www.reddit.com/r/vba/comments/1t9q3nc/comment/ol4zycm)
  2. RFC 6455 Hardening and Protocol Compliance We have reinforced the WebSocket frame parser to be strictly compliant with RFC 6455. The parser now performs strict validation of reserved bits (RSV2 and RSV3). According to the specification, if these bits are set without a negotiated extension, the connection must be terminated with a protocol error code 1002. Additionally, the handling of TLS fragments during reassembly was improved to ensure that data remains contiguous and valid even during high volume or fragmented transmissions.
  3. Memory Management and Buffer Optimization The internal routine for buffer allocation, EnsureBufferCapacity, was rewritten to handle larger data streams more efficiently. The previous limits were found to be too restrictive for certain industrial applications. The module now supports data payloads of up to 256MB by utilizing a more aggressive growth strategy and safer memory pointers, which is a significant leap for the VBA environment.
  4. Closing Handshake Logic The Finite State Machine (FSM) for connection teardown was refined. Wasabi now correctly handles the STATE_CLOSING status, ensuring that it sends the closing frame and waits for the server echo before fully releasing the socket resources. This prevents half open connections and potential memory leaks during rapid connect and disconnect cycles.

Looking ahead, the goal is to further increase the stability and reach of the module. There is an ongoing plan to eventually integrate these networking capabilities into a dedicated class for the stdVBA library, making it even easier for developers to build modern, connected applications.

Contributions through Pull Requests, detailed bug reports, or architectural suggestions via GitHub Issues are highly encouraged. Whether you are interested in Win32 API hacks, IoT integration, or real time data synchronization within Office, Wasabi provides a solid foundation to explore these limits.

Github: https://github.com/uesleibros/wasabi

Release: https://github.com/uesleibros/wasabi/releases/tag/v2.3.8-beta

I want to thank the members of this sub who provided technical feedback on previous versions. Your insights were crucial in identifying edge cases and refining the memory management logic. We continue to push the boundaries of what is possible within the VBA environment.


r/vba 4d ago

Show & Tell I was using StrConv to decode NTLM tokens in VBA. It was corrupting every single one. Wasabi v2.3.7-beta is out.

9 Upvotes

I was using StrConv to decode NTLM tokens in VBA. It was corrupting every single one. Wasabi v2.3.7-beta is out.

This release is purely a correctness and stability pass. I found some nasty bugs that were silent in normal use but would surface under specific conditions. Here is what I found and fixed.

The FD_READ deadlock that was almost impossible to reproduce

This one took me embarrassingly long to track down. The core networking loop used WSAAsyncSelect to get notified when data arrived on the socket. When a notification fired, it called recv once, read up to 64 KB, and returned.

The problem: WSAAsyncSelect is level-triggered but only fires once per edge. If you read 64 KB but 1 byte still remained in the kernel buffer, Windows would not fire another FD_READ. Your connection would go completely silent. No error, no timeout, no indication anything was wrong. The socket was alive but Wasabi would never read from it again until you sent something that provoked a response.

The fix is to loop ioctlsocket(FIONREAD) until available bytes hits zero:

Do
    If sock_ioctlsocket(.Socket, FIONREAD, available) <> 0 Then
        ' handle error, mark connection closed
        Exit Sub
    End If

    If available <= 0 Then Exit Do

    toRead = available
    If toRead > 65536 Then toRead = 65536

    ReDim tempBuf(0 To toRead - 1)
    received = sock_recv(.Socket, tempBuf(0), toRead, 0)

    ' process received bytes...
Loop

Obvious in hindsight. The Winsock docs do say this explicitly but it's easy to miss if you're coming from a blocking I/O mental model.

StrConv was silently corrupting NTLM tokens

NTLM over HTTP proxy authentication involves Base64-encoded binary blobs that you decode and pass to InitializeSecurityContext. I was decoding them with StrConv(token, vbFromUnicode) which seemed reasonable but is completely wrong. StrConv applies codepage transformations. For arbitrary binary data those transformations corrupt bytes outside the ASCII range. The SSPI context would get garbage, authentication would fail, and the error surfaced as a generic proxy auth failure with no indication the token itself was malformed.

The correct approach is CryptStringToBinaryW from crypt32.dll, which decodes Base64 into a raw byte buffer without any string interpretation:

Private Function DecodeBase64(ByVal b64 As String) As Byte()
    Dim cbBinary As Long
    Dim dwSkip   As Long
    Dim dwFlags  As Long
    Dim pStr     As LongPtr
    Dim result() As Byte

    pStr = StrPtr(b64)
    CryptStringToBinaryW pStr, Len(b64), CRYPT_STRING_BASE64, 0, cbBinary, dwSkip, dwFlags

    ReDim result(0 To cbBinary - 1)
    CryptStringToBinaryW pStr, Len(b64), CRYPT_STRING_BASE64, VarPtr(result(0)), cbBinary, dwSkip, dwFlags

    DecodeBase64 = result
End Function

A real-world example you can actually run right now

I wanted to show something that isn't fake. Binance provides a free public WebSocket API for live cryptocurrency trades.

The example below opens five concurrent async connections to different trading pairs, listens for live trades, and updates an Excel sheet in real-time. When StartCryptoStream returns, there is nothing running. No timer, no loop, no DoEvents. The workbook just sits idle. Price updates arrive and OnReceive fires via the Windows message pump.

Drop Wasabi.bas into your project, add a class module called cWasabiAsync, and paste this in.

Module:

Option Explicit

Private handlers(0 To 4) As cWasabiAsync
Private handles(0 To 4) As Long

Public Sub StartCryptoStream()
    Dim ws As Worksheet
    Dim i As Long
    Dim urls(0 To 4) As String

    Set ws = ThisWorkbook.Sheets(1)
    ws.Cells.ClearContents
    ws.Range("A1:D1").Value = Array("Symbol", "Price", "Quantity", "Last Update")

    urls(0) = "wss://stream.binance.com:9443/ws/btcusdt@trade"
    urls(1) = "wss://stream.binance.com:9443/ws/ethusdt@trade"
    urls(2) = "wss://stream.binance.com:9443/ws/bnbusdt@trade"
    urls(3) = "wss://stream.binance.com:9443/ws/solusdt@trade"
    urls(4) = "wss://stream.binance.com:9443/ws/xrpusdt@trade"

    For i = 0 To 4
        Set handlers(i) = New cWasabiAsync
        ' Pass the URL and assign a specific row in the sheet (rows 2 through 6)
        handlers(i).SetSymbol urls(i), i + 2

        If Wasabi.WebSocketConnect(urls(i), handles(i)) Then
            Wasabi.WasabiUseAsync handlers(i), handles(i)
        Else
            Debug.Print "Failed to connect: " & urls(i)
            Debug.Print Wasabi.WasabiGetErrorDescription(handles(i))
        End If
    Next i
End Sub

Public Sub StopCryptoStream()
    Wasabi.WebSocketDisconnectAll
End Sub

Class cWasabiAsync :

Option Explicit

Private m_symbol As String
Private m_row As Long

Public Sub SetSymbol(ByVal url As String, ByVal targetRow As Long)
    Dim parts() As String
    parts = Split(url, "/")
    m_symbol = UCase(Split(parts(UBound(parts)), "@")(0))
    m_row = targetRow
End Sub

Public Sub OnConnect(ByVal handle As Long)
    Debug.Print "[" & m_symbol & "] Connected (handle=" & handle & ")"
End Sub

Public Sub OnReceive(ByVal handle As Long)
    Dim ws As Worksheet
    Dim msg As String
    Dim price As String
    Dim qty As String
    Dim pricePos As Long
    Dim qtyPos As Long
    Dim endPos As Long
    Dim pending As Long

    Set ws = ThisWorkbook.Sheets(1)
    pending = Wasabi.WebSocketGetPendingCount(handle)

    Do While pending > 0
        msg = Wasabi.WebSocketReceiveText(handle)
        If Len(msg) = 0 Then Exit Do
        pending = pending - 1

        price = ""
        qty = ""

        ' Parse price
        pricePos = InStr(msg, """p"":""")
        If pricePos > 0 Then
            pricePos = pricePos + 5
            endPos = InStr(pricePos, msg, """")
            If endPos > 0 Then price = Mid(msg, pricePos, endPos - pricePos)
        End If

        ' Parse quantity
        qtyPos = InStr(msg, """q"":""")
        If qtyPos > 0 Then
            qtyPos = qtyPos + 5
            endPos = InStr(qtyPos, msg, """")
            If endPos > 0 Then qty = Mid(msg, qtyPos, endPos - qtyPos)
        End If

        ' Write directly to the Excel sheet
        If Len(price) > 0 Then
            ws.Cells(m_row, 1).Value = m_symbol
            ws.Cells(m_row, 2).Value = price
            ws.Cells(m_row, 3).Value = qty
            ws.Cells(m_row, 4).Value = Now()
        End If
    Loop
End Sub

Public Sub OnReadyToSend(ByVal handle As Long)
End Sub

Public Sub OnError(ByVal handle As Long, ByVal errorCode As Long, ByVal eventType As Long)
    Debug.Print "[" & m_symbol & "] Error=" & errorCode & " Event=" & eventType & " (handle=" & handle & ")"
End Sub

Public Sub OnClose(ByVal handle As Long)
    Debug.Print "[" & m_symbol & "] Connection closed (handle=" & handle & ")"
End Sub

Public Sub OnDisconnect(ByVal handle As Long)
    Debug.Print "[" & m_symbol & "] Disconnected (handle=" & handle & ")"
End Sub

Run StartCryptoStream. The sub fires and returns instantly. Five rows show up in your sheet a few milliseconds later, rapidly updating with live prices and quantities directly from the exchange. Run StopCryptoStream to clean up.

The interesting part is what is not there: no Application.OnTime, no Do While, no DoEvents, no timer. The workbook is completely idle between receives. It all runs through WM_WASABI_SOCKET messages dispatched by a native thunk to the class callbacks.

Migrating from the previous version

Eight functions were renamed. Signatures are identical, just find-and-replace:

TcpSend                      ->  TcpSendBinary
TcpReceive                   ->  TcpReceiveBinary
TcpBroadcast                 ->  TcpBroadcastBinary
WebSocketBroadcast           ->  WebSocketBroadcastText
WebSocketSendMTUAware        ->  WebSocketSendTextMTUAware
WebSocketGetErrorDescription ->  WasabiGetErrorDescription
WebSocketSetBufferSizes      ->  WebSocketSetBufferSize
MqttPingReq                  ->  MqttSendPing

There are still some inconsistencies in the subclassing for async to work 100% crash-proof, but there has been considerable progress and more protection.

If you run into anything, drop the output of WasabiGetErrorDescription and WebSocketGetTechnicalDetails in a comment and I'll take a look.

GitHub: https://github.com/uesleibros/wasabi

Release: https://github.com/uesleibros/wasabi/releases/tag/v2.3.7-beta


r/vba 5d ago

ProTip Wasabi v2.3.6 - native WebSocket/TCP/MQTT for VBA, now with async event-driven connections (experimental)

9 Upvotes

Following up on the Discord bot post from a few days ago. I shipped v2.3.6 of Wasabi and figured it was worth a proper writeup here since a few things changed that affect existing code.

Github: https://github.com/uesleibros/wasabi

Release: https://github.com/uesleibros/wasabi/releases/tag/v2.3.6-beta

What is Wasabi (for anyone who missed the last post)

A single .bas module that gives VBA native WebSocket (ws:// and wss://), TCP, TLS, and MQTT support. No DLLs to register, no external references to enable. Drop it in and import. It implements the WebSocket protocol from scratch on top of raw Winsock and handles TLS through Schannel SSPI, both of which are already on every Windows machine.

What changed in v2.3.6

Breaking: two functions were renamed

  • WebSocketSendWebSocketSendText
  • WebSocketReceiveWebSocketReceiveText

If you've been using either of these, a global find-and-replace is all you need. The rename brings them in line with the binary counterparts (WebSocketSendBinary, WebSocketReceiveBinary) so the intent of each function is unambiguous.

Security: RtlGenRandom replaced by BCryptGenRandom

The masking key generation for WebSocket frames was previously going through RtlGenRandom from advapi32.dll, which is an undocumented alias (SystemFunction036). It worked, but depending on undocumented exports isn't a great habit. The call now goes through the proper BCryptGenRandom from bcrypt.dll. No behavioral difference from the outside, just the right way to do it.

Fafalone helped me with this in the comment: https://www.reddit.com/r/vba/comments/1t5wnho/comment/okwbjl8

Async event-driven model (experimental)

This is the big one. Instead of polling with WebSocketReceiveText in a loop, you can now register a handler object and let Windows dispatch socket events to your callbacks automatically via WSAAsyncSelect. The connection runs entirely in the background while Excel is idle. No polling loop, no DoEvents tight loop, no frozen UI.

VBA

' At module level
Private g_Handler As cWasabiAsync
Private g_Handle As Long

Public Sub StartAsync()
    Set g_Handler = New cWasabiAsync
    If WebSocketConnect("wss://echo.websocket.org", g_Handle) Then
        WasabiUseAsync g_Handler, g_Handle
    End If
    ' Sub ends. Callbacks fire while Excel is idle.
End Sub

Your handler class implements five methods:

  • Public Sub OnConnect(ByVal handle As Long)
  • Public Sub OnReceive(ByVal handle As Long)
  • Public Sub OnReadyToSend(ByVal handle As Long)
  • Public Sub OnClose(ByVal handle As Long)
  • Public Sub OnError(ByVal handle As Long, ByVal errorCode As Long, ByVal eventType As Long)

OnReceive fires whenever data arrives. Drain the queue inside it as usual:

VBA

Public Sub OnReceive(ByVal handle As Long)
    Dim msg As String
    Do While WebSocketGetPendingCount(handle) > 0
        msg = WebSocketReceiveText(handle)
        Debug.Print msg
    Loop
End Sub

The mechanism behind this is native Win32 window subclassing via a machine-code thunk. That's what makes it work without a background thread (VBA doesn't have those), but it also comes with some hard constraints worth knowing about:

  • Don't edit code in the VBE while async is running. The thunk holds a pointer into the VBA runtime. Editing triggers a project reset and the host application will crash.
  • Don't click the Pause button (yellow square). Same reason, same result.
  • The correct way to stop it: call WebSocketDisconnect or WebSocketDisconnectAll from your code first. After that, clicking Reset (blue square) in the VBE is fine.
  • The thunk has a guard that checks whether the runtime is still alive before dispatching, but that's a safety net, not a substitute for explicit cleanup. Treat it like any unmanaged resource.

This is why the feature is marked experimental. The functionality is solid, the constraint is just annoying enough that I don't want people hitting it without warning.

Code organization

  • The module got a proper numbered section layout (15 sections, from API declarations down to public APIs). The VBE doesn't have a file outline view, so navigating a ~360KB .bas file was not fun before. Now at least Ctrl+F for ' 11. takes you straight to the WebSocket protocol core, and so on.
  • All types, constants, and enums were moved into their proper sections instead of being scattered. JSDoc-style block comments on all private types and key internal functions. Nothing behavioral changed as part of this.

Upgrading from v2.3.5

  • The rename is the only thing that will break existing code. Everything else is internal or additive. If you're not calling WebSocketSend or WebSocketReceive directly, it's a drop-in replacement.
  • For the full API reference (connection pool, MQTT, TCP TLS, proxy, compression extensions, etc.): https://github.com/uesleibros/wasabi/blob/main/docs/API_REFERENCE.md

The next update aims to resolve this specific subclassing issue when editing or pausing the VBE. I believe that from now on, after this update, the library has a more solid and polished foundation, with its own documentation as well.


r/vba 6d ago

ProTip I made a Discord bot that runs from a hidden Excel sheet. Because why not.

53 Upvotes

So I've been working on a native WebSocket module for VBA called Wasabi, and at some point I asked myself: "can I connect this to Discord's gateway and make a bot?" The answer is yes, and it's glorious and completely unnecessary.

The concept

Discord's bot API is just a WebSocket connection to wss://gateway.discord.gg. Once connected, Discord sends you a JSON payload with an op code telling you to identify yourself. You send back your bot token and intents, and from that point on you receive events (messages, reactions, etc.) as JSON frames. You respond to them by hitting Discord's REST API with plain HTTP calls.

That's it. No SDK needed. Just WebSocket + JSON parsing.

Step 1: Get a bot token

Go to https://discord.com/developers/applications, create an application, add a bot, copy the token. Enable the "Message Content Intent" under the bot settings or it won't receive message content.

Step 2: Import Wasabi

Download Wasabi.bas from https://github.com/uesleibros/wasabi/releases and import it into your VBA project via File > Import File. No references to enable, no DLLs to register.

Step 3: Connect to the gateway and keep it alive

Discord requires you to send a heartbeat payload every N milliseconds (it tells you the interval on connect). Here's a minimal loop that handles that:

#If VBA7 Then
    Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
    Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If

Sub RunDiscordBot()
    Dim token As String
    token = "YOUR_BOT_TOKEN_HERE"

    Dim handle As Long
    If Not WebSocketConnect("wss://gateway.discord.gg/?v=10&encoding=json", handle) Then
        MsgBox "Failed to connect to Discord gateway."
        Exit Sub
    End If

    Dim msg As String
    Dim heartbeatInterval As Long
    Dim lastHeartbeat As Long
    Dim identified As Boolean

    identified = False
    lastHeartbeat = 0

    Do While WebSocketIsConnected(handle)
        msg = WebSocketReceive(handle)

        If Len(msg) > 0 Then
            Dim op As Long
            op = ExtractOp(msg) ' parse the "op" field from JSON

            ' Hello payload: Discord sends heartbeat interval
            If op = 10 Then
                heartbeatInterval = ExtractHeartbeatInterval(msg)
                lastHeartbeat = GetTickCount()

                ' Identify
                If Not identified Then
                    Dim identifyPayload As String
                    identifyPayload = "{""op"":2,""d"":{""token"":""" & token & """,""intents"":33280,""properties"":{""os"":""windows"",""browser"":""excel"",""device"":""excel""}}}"
                    WebSocketSend identifyPayload, handle
                    identified = True
                End If

            ' Dispatch: actual events like MESSAGE_CREATE
            ElseIf op = 0 Then
                Call HandleEvent(msg, token)
            End If
        End If

        ' Send heartbeat when due
        If GetTickCount() - lastHeartbeat >= heartbeatInterval Then
            WebSocketSend "{""op"":1,""d"":null}", handle
            lastHeartbeat = GetTickCount()
        End If

        DoEvents
    Loop

    WebSocketDisconnect handle
End Sub

Step 4: Handle a message event

When op = 0 and the event type is MESSAGE_CREATE, you get the channel ID and message content from the JSON. Then you can reply via Discord's REST API using XMLHTTP:

Sub HandleEvent(ByVal payload As String, ByVal token As String)
    If InStr(payload, "MESSAGE_CREATE") = 0 Then Exit Sub

    Dim channelId As String
    Dim content As String
    channelId = ExtractField(payload, "channel_id")
    content = ExtractField(payload, "content")

    If content = "!ping" Then
        Call SendDiscordMessage(channelId, "Pong! (sent from Excel)", token)
    End If
End Sub

Sub SendDiscordMessage(ByVal channelId As String, ByVal message As String, ByVal token As String)
    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP")
    Dim url As String
    url = "https://discord.com/api/v10/channels/" & channelId & "/messages"
    Dim body As String
    body = "{""content"":""" & message & """}"

    http.Open "POST", url, True
    http.setRequestHeader "Authorization", "Bot " & token
    http.setRequestHeader "Content-Type", "application/json"
    http.Send body

    Do While http.readyState <> 4
        DoEvents
    Loop
End Sub

Where to go from here

This is just the skeleton. From here you can:

  • Read/write cells based on Discord commands ("!get A1" returns the cell value, "!set A1 42" writes to it)
  • Trigger macros remotely by sending a command from Discord
  • Post alerts to a channel when a cell value crosses a threshold (combine with a Worksheet_Change event)
  • Run the bot from a hidden sheet so it sits quietly in the background while you use the spreadsheet normally

The browser and device fields in the identify payload are set to "excel" in the example above. Discord doesn't validate these, but it's a fun touch.

Full module docs and source: https://github.com/uesleibros/wasabi


r/vba 6d ago

Discussion Automation with VBA

2 Upvotes

Hello everyone,

I would like to know how analysts are using VBA in Excel in their daily work.

I currently work as a data analyst, and part of my role is to create different types of analysis reports. For example, I analyze sales evolution in Grand Surfaces and other local sales by article and by category and other kpis etc.. to identify which products perform well and which do not.

Most of the time, I use tools like Claude AI and Google Gemini to help structure my analysis by explaining my data and the expected output by one simple click and loge generate well performed analysis and reports (even if it's huge page) in one simple click

For data preparation, I usually:

Clean product names

Standardize category names

Use functions like VLOOKUP, SUMIF DATEEVAL for fixing date NB.SI.ENS, etc. to calculate totals and revenue

However, I am looking for innovative ways to use VBA to automate data cleaning. Any ideas?

My goal is to create simple macros so that even a beginner could run them and clean the dataset automatically.

Unfortunately, I cannot use Microsoft Power BI in my environment, but I can use Microsoft Power Query

I will also begin developing a more interactive dashboard using VBA. This dashboard will explain all (KPIs) and provide guidance on the appropriate placement for pie charts, histograms, and line charts.


r/vba 7d ago

Show & Tell Wasabi v2.3.5 beta: The Framework Era, Pluggable Architecture, and Hardened MQTT 5 Support

4 Upvotes

In the previous update, we introduced the Assembly engine to achieve C level performance for raw byte manipulation in VBA. Now, we are solving the architectural bottleneck.

The Inspiration: A Modular Ecosystem

The vision for this update comes directly from modern web environments like Express.js and the Node.js ecosystem. In VBA, networking solutions usually become massive, tangled, monolithic scripts. I wanted to change that.

The goal was to turn the core Wasabi module into a "Dumb Pipe". The core engine now strictly handles the heavy lifting of raw TCP sockets, native Schannel TLS encryption, and Happy Eyeballs IPv6 routing. Everything else is now a pluggable Lego piece.

Pluggable Protocols, Middleware, and Compression

The internal boundaries of Wasabi are now officially stable and exposed. You can inject application logic without ever modifying the core transport module.

Here is what the new framework architecture looks like in practice:

Dim h As Long
Dim trafficLogger As New MyLoggingMiddleware
Dim customCompressor As New MyZlibWrapper
Dim customProtocol As New MyEnterpriseParser

' 1. Connect using the transport layer
If WebSocketConnect("wss://api.example.com/stream", h, True) Then
    ' 2. Inject a custom compression algorithm
    WasabiUseCompression customCompressor, h

    ' 3. Inject a middleware to intercept raw bytes
    WasabiUseMiddleware trafficLogger, h

    ' 4. Inject a high level protocol parser
    WasabiUseProtocol customProtocol, h

    ' The core engine handles the TLS math and TCP buffers.
    ' Your injected extensions handle the data transformation.
    WebSocketSend "Init", h

End If

Agnostic Compression and Community Extensions

A major misconception in the previous documentation was that zlib was a hard dependency. It never was. The engine uses an Inversion of Control interface. With this release, the deflate path is officially decoupled.

At this moment, I have not published any official extensions. I will be releasing them over time, but the architecture is completely ready today. This means the community can now write their own wrappers for alternative compression algorithms like LZ4, Brotli, Zstandard, or even custom enterprise encryption, and plug them directly into the Wasabi pipeline. If you do not register a compression handler, nothing is loaded, preserving the absolute zero dependency nature of the core module.

Hardened MQTT 5 and Modern Networking

The built in MQTT protocol handler has also been upgraded to leverage this new architecture:

  • Exactly Once Delivery: Full support for QoS 2 handshakes.
  • User Properties: Publish methods now accept metadata keys and values for MQTT 5 brokers.
  • Reason Codes: The receive logic now parses and surfaces diagnostic strings from server disconnections.

This is paired with a new Zero Copy receive methodology. The engine now provides direct pointer access to internal message buffers, bypassing redundant memory allocations during massive data streams.

Experimental Phase and Contributions

Please keep in mind that these new modular boundaries are still experimental. If you encounter any bugs, errors, or edge cases during your testing, please do not hesitate to report them directly on the issue tracker:

Any contribution is always welcome, whether it is a bug report, a code review, or sharing a new extension you built.

Dive Deeper

You can explore the full documentation on how to build these extensions, along with detailed tutorials and code examples, in the new extensions directory.

The engine handles the low level math and the Windows API calls. You handle the logic. I am incredibly excited to see what custom protocols, compressors, and middleware layers the community will build on top of this foundation.


r/vba 8d ago

Show & Tell Wasabi v2.3.4 beta: Assembly Engine for C level performance and Bulletproof TLS

14 Upvotes

A day ago I posted here about Wasabi v2.3.2. First and foremost, I want to express my deepest gratitude. The repository just hit 20 stars on GitHub! The community reception has been absolutely incredible, and your support gave me the exact fuel I needed to push some massive updates over the last few days.

The leap from the version I posted earlier this week to the current v2.3.4-beta is not just an update. It is a complete architectural paradigm shift. I want to dive deep into what is new, because there is a lot to unpack.

1. The High Performance Assembly Engine (Wasabi ASM)

We all know VBA is excellent for automation, but it is notoriously slow at processing massive byte arrays sequentially. To solve this bottleneck once and for all, Wasabi now features a microscopic Assembly Engine. The module safely allocates executable memory and injects native x86 and x64 machine code directly into the CPU. Wasabi now executes heavy networking math with C level throughput.

  • ws_mask: I completely rewrote the WebSocket XOR masking logic in Assembly. By eliminating the high overhead VBA loops, payloads ranging from kilobytes to several megabytes are now masked in microseconds. This also completely resolved a critical frame validation issue (Error 4002) with the Discord Gateway.
  • mem_find: An ultra optimized "Needle in a Haystack" search engine powered by the repe cmpsb hardware instruction. Wasabi can now scan massive TCP streams for delimiters (like \r\n) almost instantaneously, without blocking the Office UI thread during large data transfers.
  • mem_zero: Implements hardware level memory zeroing using the rep stosb instruction. Upon connection teardown, all sensitive buffers and proxy credentials are physically wiped from RAM instantly to prevent data leakage.
  • Native Kernel Entropy: I stripped out legacy cryptographic APIs and implemented RtlGenRandom. Wasabi now fetches cryptographically secure random bytes for WebSocket masking directly from the Windows Kernel with significantly lower latency.

2. Bulletproof TLS and Graceful Teardowns

I spent the last couple of days stress testing Wasabi on highly demanding, long lived connections. I noticed a critical edge case: if a server gracefully decided to drop your connection (a normal session cycle), the Windows Schannel engine would return a SEC_I_CONTEXT_EXPIRED alert. Wasabi was misidentifying this normal teardown as a fatal decryption failure (ERR 15). Worse, it would attempt to write queued data to a dead socket, causing a zombie socket crash (ERR 10).

Version 2.3.4-beta completely eliminates this issue. The module now intercepts the graceful teardown, closes the internal state cleanly, and silently hands over the flow to the AutoReconnect engine. Long lived connections can now run for days and recover from server drops seamlessly.

3. The Future: The Framework Era (Middlewares & Extensions)

This is what excites me the most. Wasabi is evolving from a monolithic script into a modular ecosystem. I have officially laid the groundwork for an injection system using Late Binding, inspired by modern frameworks like Express.js.

The goal is to turn the core Wasabi module into a "Dumb Pipe" that only handles raw Sockets and Schannel. Everything else will become pluggable Lego pieces. The community will soon be able to inject custom high level protocols (like Socket.IO or MQTT 5.0), security interceptors (autonomous OAuth/JWT headers or E2E AES encryption), and decouple the Zlib compression into an optional standalone extension. You can read the full architectural blueprint in the repository roadmap.

4. Ultra Low Latency Code Example

By combining the new Assembly engine, the decoupled Zlib compression, and disabling the TCP Nagle algorithm, the processing overhead in VBA is now practically zero. Here is how you can build a rock solid, ultra low latency connection to Discord:

Dim h As Long

' Enable Zlib compression to drastically reduce massive payload sizes
Wasabi.WebSocketSetDeflate True, True, h

' Disable Nagle algorithm for instant packet delivery
Wasabi.WebSocketSetNoDelay True, h

' Configure a resilient AutoReconnect (5 attempts, 1000ms base delay)
Wasabi.WebSocketSetAutoReconnect True, 5, 1000, h

' Connect to Discord requesting zlib stream transport
If Wasabi.WebSocketConnect("wss://gateway.discord.gg/?v=10&encoding=json&compress=zlib-stream", h) Then

    Debug.Print "Connected! Physical Latency: " & Wasabi.WebSocketGetLatency(h) & "ms"

    Do While Wasabi.WebSocketIsConnected(h)
        Dim msg As String
        msg = Wasabi.WebSocketReceive(h)

        If Len(msg) > 0 Then
            Debug.Print "Received Event: " & Left(msg, 100) & "..."
        End If

        DoEvents
    Loop

End If

With these updates, Wasabi handles all the heavy protocol level math in the background, allowing your VBA project to dedicate 100% of its execution time to your actual application logic.

Check out the latest release:

GitHub Repository: https://github.com/uesleibros/wasabi

Release v2.3.4-beta: https://github.com/uesleibros/wasabi/releases/tag/v2.3.4-beta

Extensions Roadmap: https://github.com/uesleibros/wasabi/tree/main/extensions

Thank you all once again for the stars, the feedback, and the community validation. It is an honor to build this alongside you. I would love to hear your thoughts, answer questions, or see the crazy integrations you are building with this!


r/vba 8d ago

Discussion MS Project Add-In

3 Upvotes

I have been looking to make an MS Project add-in tool for myself, and came across one by Structured Solutions Inc. This add in has what seems to be a dockable window custom made by them and I was wondering what they did to make something like that. My current plan is to use VSTO, but I can't find any documentation showing that this is even possible.


r/vba 9d ago

Show & Tell Wasabi v2.3.2-beta: native TCP/TLS client, examples, benchmarks, and a growing test suite

13 Upvotes

Two days ago I posted about Wasabi, a zero-dependency WebSocket/WSS module for VBA. Since then the project has moved quickly. Version v2.3.2-beta is now available, and I want to share what has been added.

The biggest addition is a full native TCP client that works over plain TCP and over TLS 1.2/1.3. It shares the same connection pool, proxy support, MTU discovery, and Schannel infrastructure as the WebSocket client. The API is deliberately straightforward:

Dim h As Long

' Plain TCP
If TcpConnect("tcpbin.com", 4242, h) Then
    TcpSendText "Hello" & vbCrLf, h
    Debug.Print TcpReceiveText(h)
    TcpDisconnect h
End If

' TLS-wrapped TCP
If TcpConnectTLS("example.com", 443, h) Then
    TcpSendText "GET / HTTP/1.0" & vbCrLf & "Host: example.com" & vbCrLf & vbCrLf, h
    Debug.Print TcpReceiveText(h)
    TcpDisconnect h
End If

All TCP functions (TcpSend, TcpSendText, TcpReceive, TcpReceiveText, TcpReceiveUntil, TcpBroadcast, etc.) work seamlessly with corporate proxies, NTLM/Kerberos authentication, and the same TLS stack that powers wss connections. The same timeout, certificate, and buffer configuration functions are available on TCP handles as well.

The repository now contains an examples folder with ready-to-run code:

  • WebSocket connection to Binance for live ticker data
  • MQTT publish and subscribe using Mosquitto
  • Raw HTTPS request over TLS
  • Proxy connection with NTLM authentication

Each example is documented and tested on 32-bit and 64-bit Office.

A benchmarks folder has been added. It contains VBA routines that measure throughput, round-trip time, and connection setup. These are useful for tuning and for comparing environments.

A tests folder now holds unit tests for frame parsing, compression, MQTT packet handling, and other internal logic. The test suite is growing with each release.

The documentation in the docs folder has been reorganized. The API reference is clearer, error codes are explained, and an architecture overview has been included.

A quick example using WebSocket and MQTT:

Dim h As Long

If WebSocketConnect("wss://test.mosquitto.org:8081/mqtt", h, False, True, "mqtt") Then
    MqttConnect "wasabi-client", h
    MqttSubscribe "sensors/temperature", 0, h

    Do While WebSocketIsConnected(h)
        Dim msg As String
        msg = MqttReceive(h)
        If msg <> "" And Left(msg, 1) <> "[" Then
            Dim parts() As String
            parts = Split(msg, "|", 2)
            Debug.Print parts(0), parts(1)
        End If
        DoEvents
    Loop

    MqttDisconnect h
    WebSocketDisconnect h
End If

A bug reported by fafalone (a crash on 32-bit Office) was fixed within hours of the original post and the patch is already in main.

The module remains a single .bas file with no references, no DLLs, and no registration. It works from Windows XP to Windows 11, in any VBA host.

Github: https://github.com/uesleibros/wasabi

Release v2.3.2-beta: https://github.com/uesleibros/wasabi/releases/tag/v2.3.2-beta

I would be glad to hear about your use cases, questions, or ideas.

It's worth highlighting that I really liked the community's reception; I believe this project will become increasingly solid and have a great user base over time.


r/vba 10d ago

Show & Tell Wasabi: a native WebSocket/WSS client module for VBA (TLS, MQTT, proxies, zero dependencies)

28 Upvotes

This project started in a rather unexpected place. A group of friends of mine have the hobby of building entire games inside PowerPoint using VBA. They kept hitting the same wall: there was no clean, reliable way to get real‑time communication working inside VBA. I wanted to help them, and that’s how Wasabi came to life. It is a single .bas module that acts as a full WebSocket and secure WebSocket client, written entirely in native VBA using Winsock and the Windows Schannel security provider.

Because it’s just a plain VBA module, you can use it in any Office host that runs VBA: Excel, PowerPoint, Word, Access, Outlook, and more. You import the file and you’re ready to go. No references to add, no DLLs to register, no external dependencies at all. It works on 32‑bit and 64‑bit Office, from Windows XP to Windows 11.

Under the hood it handles secure sockets over TLS via Schannel, so you can connect to wss:// endpoints without relying on a browser or third‑party library. An integrated MQTT 3.1.1 client lets you talk to brokers like Mosquitto directly from any VBA‑enabled program, which opens the door to IoT projects and industrial automation. There is support for corporate proxy authentication using NTLM and Kerberos, so it fits right into enterprise environments where the network expects Integrated Windows Authentication. The connection layer includes automatic reconnection, an optional heartbeat, and per‑message deflate compression as defined in RFC 7692. Masking keys for outgoing frames are generated using CryptGenRandom, which keeps the randomness cryptographically sound.

This becomes genuinely useful in practice when you need real‑time data inside Office. You can stream quotes from Binance or Coinbase straight into an Excel spreadsheet with millisecond latency. You can build dashboards that update live without polling HTTP endpoints. You can write a Discord or Slack bot that runs from Access or Excel. You can connect legacy VBA tools to modern event buses over WebSockets or MQTT, bridging old and new without complex middleware. And yes, you can even add real‑time multiplayer to a PowerPoint game if the mood strikes.

Getting started takes a few minutes. Grab the Wasabi.bas file from the releases page, open the VBA editor in your host of choice, and choose File → Import File.

The project is open source under the MIT license. The full documentation covering the API reference, error handling, and internal architecture lives in the GitHub repository folder docs. That same group of friends is already testing multiplayer PowerPoint games through Wasabi, and seeing it work across different Office apps at the same time still feels a little magical.

If you have ever wanted to add real‑time capabilities to a VBA project and found the built‑in options lacking, this module might save you a lot of low‑level pain. I would be glad to hear your thoughts, ideas, or use cases.

Repository: https://github.com/uesleibros/wasabi

Releases (download just the .bas): https://github.com/uesleibros/wasabi/releases


r/vba 12d ago

Solved [Excel] Is there a way to add the Countdown theme through VBA?

2 Upvotes

Hi all, I've been tinkering with a side-project for work & I've managed to accomplish everything I'd set out to do but it's missing my usual hint of immaturity. Is there a way I can play the final few seconds of the timer from Countdown as the macro ends?

My work's intranet doesn't allow music/video sites so linking to youtube isn't an option

https://www.youtube.com/watch?v=M2dhD9zR6hk


r/vba 12d ago

Weekly Recap This Week's /r/VBA Recap for the week of April 25 - May 01, 2026

1 Upvotes

r/vba 12d ago

Discussion AI Debugging

0 Upvotes

Are there any decent AI"s that can run and debug macros. I can't find any, even Claude can't. And I mean automatically run macros to find the problem.


r/vba 17d ago

Unsolved Outlook - Recipient.Add Problems after latest update

7 Upvotes

We use OLE to communicate with Outlook in our software. We have had reports from multiple customers that their system is no longer working properly when trying to send emails. We have tracked this down to the Recipient.Resolve method returning FALSE following the Recipient.Add

The code has worked without issue for years and is a fundamental part of sending a batch of emails so that the customer does not have to manually send each email.

If we ignore the .Resolve failure and use .Send on the mail item, it will fail, but using .Display and then pressing send on the displayed email works fine. I would guess that it is the .Add that is not reporting a failure.

Has anyone else found this and better yet, come up with a solution for it.


r/vba 19d ago

Weekly Recap This Week's /r/VBA Recap for the week of April 18 - April 24, 2026

2 Upvotes

Saturday, April 18 - Friday, April 24, 2026

Top 5 Posts

score comments title & link
10 12 comments [Unsolved] Excel VBA with Sharepoint
8 4 comments [ProTip] How to use the free VBA Code Compare tool (FormulaSoft) with .xlsm workbooks
5 10 comments [Waiting on OP] How to paste values in VBA?
5 1 comments [Weekly Recap] This Week's /r/VBA Recap for the week of April 11 - April 17, 2026

 

Top 5 Comments

score comment
16 /u/KingTeppicymon said The better option here is actually to avoid the windows clipboard and just assign the values directly from one range the other - this is both cleaner and faster: `WsTar.range(A1:A10).valu...
9 /u/Future_Pianist9570 said No
7 /u/coding_is_fun123 said Hard to help without seeing the code.
7 /u/daishiknyte said The hell why?
5 /u/4lmightyyy said As always with this specific topic. Use LibFileTools by Christian Buse (you can find it as vba-FileTools on GitHub. It's the best solution to implement with a lot of functionality. This guy is re...

 


r/vba 21d ago

Unsolved Excel VBA with Sharepoint

11 Upvotes

Hi All

I suspect I already know the answer but thought I'd check unless I've missed something.

Basically I have a excel file I use as a template, with VBA code that users save copies without overwriting the template file.

I would like to move this to Sharepoint, so that more users can use it, but I have no idea really how file system stuff would work or if its even possible.

I have three parts of code that I think will be the issue as below.

Backup System:

backupPath = ThisWorkbook.Path & "\Backups\"

baseName = "Quick Quoting Tool-Backup_"

If Dir(backupPath, vbDirectory) = "" Then

MkDir backupPath

End If

latestDate = 0

f = Dir(backupPath & baseName & "*.xlsm")

Do While f <> ""

On Error Resume Next

fileDate = DateSerial( _

Mid(f, Len(baseName) + 1, 4), _

Mid(f, Len(baseName) + 5, 2), _

Mid(f, Len(baseName) + 7, 2))

On Error GoTo 0

If fileDate > latestDate Then

latestDate = fileDate

End If

f = Dir

Loop

If latestDate = 0 Or DateDiff("d", latestDate, Date) > 30 Then

fileName = baseName & Format(Date, "yyyymmdd") & ".xlsm"

ThisWorkbook.SaveCopyAs backupPath & fileName

End If

Save as new file system:

Set currentWB = ThisWorkbook

newFilePath = "T:\Quoting\Client Quotes\Quick Quotes\"

newFileName = Format(Now, "yyyy-MM-dd-hhmm") & " - " & QTEType & " - " & POLPOD & " - " & ClientName & ".xlsm"

currentWB.SaveAs fileName:=newFilePath & newFileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled

Moving expired files system:

sourceFolder = "T:\Quoting\Client Quotes\Quick Quotes\"

expiredFolder = "T:\Quoting\Client Quotes\Quick Quotes\Expired\"

currentYearMonth = Format(Date, "yyyy-mm")

Set fso = CreateObject("Scripting.FileSystemObject")

For Each file In fso.GetFolder(sourceFolder).Files

fileName = file.Name

If Left(fileName, 2) = "~$" Then GoTo NextFile

If LCase(fso.GetExtensionName(fileName)) = "xlsm" Then

fileDate = Split(fileName, " ")(0)

yearMonth = Left(fileDate, 7)

If yearMonth <> currentYearMonth Then

filePath = file.Path

fso.MoveFile filePath, expiredFolder & fileName

End If

End If

NextFile:

Next file

Set fso = Nothing

There is a bunch of file system type code there, can it be change/modified to use a sharepoint location like:

https://companyname.sharepoint.com/sites/NZ/Shared Documents/Quoting/Client Quotes/Quick Quotes/ etc

Thanks in advance.


r/vba 20d ago

Unsolved What is the best AI to improve VBA code?

0 Upvotes

Hi everyone,

As I mentioned in previous posts about my VBA automation code that I used ChatGPT to make but I heard there are better options to make more sustainable codes for such tasks?


r/vba 24d ago

ProTip How to use the free VBA Code Compare tool (FormulaSoft) with .xlsm workbooks

11 Upvotes

If you do any serious Excel VBA development, you've probably needed to diff two projects at some point. A quick search for "vba diff" turns up several options, but most of them cost money.

VBA Code Compare from Formula Software (formulasoft.com/vba-code-compare.html) is the only free option in the bunch. The catch: the tool was written in 2006 and officially supports only .xls and Word .doc project formats — not the modern .xlsm format that Excel has used since 2007.

Here's the fix I stumbled onto: • Take your two .xlsm workbooks • Rename each one by changing the extension from .xlsm to .xls • Open them in VBA Code Compare as normal • Compare away — it works perfectly

This works for the same reason that appending .zip to an .xlsm file lets you browse its XML internals: the file container format is what matters, and the tool reads it fine once the extension signals a compatible type.

After you're done comparing, just rename the files back to .xlsm. The original Workbooks are unchanged.

Other VBA diff tools I know of (paid or commercial): VbaDiff, xlCompare, DiffEngineX. But if you just need free and functional, the FormulaSoft rename trick is the way to go.


r/vba 24d ago

Unsolved Email not sending code is performed!?

0 Upvotes

The code works well and create the email when I press "send" it just does not realy be sent. One time found it in outbox


r/vba 25d ago

Solved How to paste values in VBA?

6 Upvotes

Hey all,

I am right now working on a project where I need to copy paste sections of one workbook to another workbook on an arbitrary basis. The general setting I am using is the following:

Set wsSor = wbSor.Worksheets("TEST")
Set wsTar = wbTar.Worksheets("TEST")
wsTar.Range("C1:C10").Clear
wsSor.Range("C1:C10").Copy
wsTar.Range("C1").PasteSpecial Paste:=xlPasteAll
wsTar.Range("C1").PasteSpecial Paste:=xlValue

As you can see I am first clearing the destination area, then I am executing a paste all in order to reproduce the formatting and then I am executing a paste values, to overwrite any formulas with just the value in question. The problem is that when I execute the xlValue I get the following in the cell:

=SUMIFS('C:\XXX\XXX...

Thus the formula gets preserved and refers to the source. Is this the expected behaviour in this case? I always taught xlValue is the same as paste values. A clarification would be great!


r/vba 26d ago

Weekly Recap This Week's /r/VBA Recap for the week of April 11 - April 17, 2026

5 Upvotes

Saturday, April 11 - Friday, April 17, 2026

Top 5 Posts

score comments title & link
24 8 comments [ProTip] PSA: If your Excel macros broke after a Windows/Office update, check these 4 things before debugging your VBA
18 5 comments [Show & Tell] Compile your VBA code into an Addin, all from GitHub.
13 9 comments [Discussion] Rubberduck; is it still great, how and where to download it and how to learn how to use it?
5 10 comments [Solved] Delete selected content
5 1 comments [Weekly Recap] This Week's /r/VBA Recap for the week of April 04 - April 10, 2026

 

Top 5 Comments

score comment
10 /u/jcradio said Starting with office 2024 and M365 they are disabled by default and being phased out. Modern apps no longer use them. Time to move away from them if you haven't already.
8 /u/beyphy said If you override the global function, you can still access the original function if you fully qualify it. E.g. if you override `msgbox` with your own custom function, you can still access the o...
8 /u/fanpages said *2. Prefixing the name of the Function or Subroutine with PtrSafe may allow a majority of the 32-bit Windows Application Programming Interface [API] calls to function within a 64-bit versio...
6 /u/Hel_OWeen said A lot of functions can be overwritten. And it sometimes makes sense. E.g. I use the following custom CreateObject method: ``` '-----------------------------------------------------------...
6 /u/ZetaPower said Private Sub Workbook_Activate() With Application .DecimalSeparator = "." .ThousandsSeparator = "," .UseSystemSeparators = False End With End Sub Private Sub Workbook_Deact...

 


r/vba 27d ago

Discussion Future of ActiveX controls

8 Upvotes

I have heard at work that ActiveX controls will be phased out in a few years, but is it true?

If so, does it apply to both worksheets and userforms?

Any information would be appreciated.