Using VBA to force drag cell in cut manner

Vrilx

New Member
Joined
Jul 25, 2019
Messages
7
Hey guys,

I need some help with a sheet i am trying to create.

The idea is to have a list of cells B3,B4.B5.B6 for example and the user is able to drag B5 to the top of the list and the sheet automatically move B3 to B4, B4 to B5 etc. Just like the way you would if you selected B5 and held the shift key while showing the move pointer and dragged the cell up.

Is there a code or option i can use to ensure this is defaulted to manipulate excel to think that the user has held the shift key down?

In addition: is there then a way to force the move pointer onto the cell without having to find the bottom boarder?
 

Excel Facts

What does custom number format of ;;; mean?
Three semi-colons will hide the value in the cell. Although most people use white font instead.
Maybe this will crudely help:

Item 1Item 2<< moved to the top
Item 2<<Click and drag to the top but using ShiftItem 1<< moved down one space
Item 3Item 3<< Didn't move
 
Upvote 0
What's the problem with holding down the SHIFT key while dragging ?
 
Upvote 0
While for normal people not an issue I want to make the file as idiot proof as possible hence the wonder if this can be done.
 
Upvote 0
Sorry, I don't know if excel has a setting for what you want to do.

As for a vba solution, I don't think it is going to be easy because dragging cells locks code execution. Maybe someone else can think of a workaround.
 
Upvote 0
Ok- I have given this another try and the following worked for me :

Workbook Demo


-Add this code to a new Standard Module and run the "Start Test" Macro .... To stop monitoring the mouse dragging operations, run the "Stop Test" Macro.
VBA Code:
Option Explicit

Type POINTAPI
    X As Long
    Y As Long
End Type

#If VBA7 Then
    #If Win64 Then
        Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
        Declare PtrSafe Function DragDetect Lib "user32" (ByVal hWnd As LongPtr, ByVal pt As LongLong) As Long
    #Else
        Declare PtrSafe Function DragDetect Lib "user32.DLL" (ByVal hWnd As LongPtr, pt As POINTAPI) As Long
    #End If
    Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
    Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
    Declare PtrSafe Function KillTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
    Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
    Declare PtrSafe Function GetCursorPos Lib "user32.DLL" (lpPoint As POINTAPI) As Long
    Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Declare PtrSafe Function AccessibleChildren Lib "oleacc" (ByVal paccContainer As Any, ByVal iChildStart As Long, ByVal cChildren As Long, ByRef rgvarChildren As Any, ByRef pcObtained As Long) As Long
#Else
    Declare Function DragDetect Lib "user32.DLL" (ByVal hWnd As Long, pt As POINTAPI) As Long
    Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
    Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
    Declare Function GetCursorPos Lib "user32.DLL" (lpPoint As POINTAPI) As Long
    Declare Function GetActiveWindow Lib "user32" () As Long
    Declare Function AccessibleChildren Lib "oleacc" (ByVal paccContainer As Any, ByVal iChildStart As Long, ByVal cChildren As Long, ByRef rgvarChildren As Any, ByRef pcObtained As Long) As Long
#End If



Sub StartTest()
    ModifyCellDrag = True
End Sub


Sub StopTest()
    ModifyCellDrag = False
End Sub



Property Let ModifyCellDrag(ByVal Modify As Boolean)

    KillTimer Application.hWnd, 0

    If Modify Then
        SetTimer Application.hWnd, 0, 0, AddressOf MonitorMouseDragging
    End If

End Property


Private Sub MonitorMouseDragging()

    Const KEYEVENTF_KEYUP = &H2
    Const VK_LSHIFT = &HA0
    Const CHILDID_SELF = 0&
    Const NAVDIR_FIRSTCHILD = &H7

    Dim tCurPos As POINTAPI
    Dim oIacc As IAccessible, vAcc As Variant, i As Long


    'Stop Timer if inside the VBE to avoid potential problems !
    If IsVBEActive Then
        keybd_event VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0
        KillTimer Application.hWnd, 0
        Exit Sub
    End If

    If GetActiveWindow = Application.hWnd Then
        Set vAcc = Application.CommandBars("status Bar")
        Set oIacc = vAcc.accNavigate(NAVDIR_FIRSTCHILD, CHILDID_SELF)
        For i = 1 To 6
            Set oIacc = oIacc.accNavigate(NAVDIR_FIRSTCHILD, CHILDID_SELF)
        Next
        GetCursorPos tCurPos
        #If Win64 Then
            Dim lPt As LongPtr
            CopyMemory lPt, tCurPos, LenB(lPt)
            If DragDetect(Application.hWnd, lPt) = 1 Then
        #Else
            If DragDetect(Application.hWnd, tCurPos) = 1 Then
        #End If
                If InStr(1, oIacc.accName(0&), "Drag to move", vbTextCompare) Then
                    keybd_event VK_LSHIFT, 0, 0, 0
                End If
            Else
                keybd_event VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0
            End If
    End If

End Sub


Private Function IsVBEActive() As Boolean
    IsVBEActive = CBool(GetActiveWindow = FindWindow("wndclass_desked_gsk", vbNullString))
End Function


Private Sub Auto_Close()
    ModifyCellDrag = False
End Sub


Remarks:
1- Code written and tested in Excel 2016 64bit
2- The above code is language dependent ... should work fine in English versions of excel... For other languages, the code must be slightly amended.
 
Last edited:
Upvote 0
32bit.

that code has literally made the file so much better for idiot proofing the movement up and down

thanks again
 
Upvote 0
32bit.

that code has literally made the file so much better for idiot proofing the movement up and down

thanks again
Thanks ... Is that excel 2007, 2010, 2013 , 2016 which version ?
 
Upvote 0

Forum statistics

Threads
1,214,990
Messages
6,122,625
Members
449,093
Latest member
catterz66

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top